linux/fs/f2fs/xattr.c
<<
>>
Prefs
   1/*
   2 * fs/f2fs/xattr.c
   3 *
   4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
   5 *             http://www.samsung.com/
   6 *
   7 * Portions of this code from linux/fs/ext2/xattr.c
   8 *
   9 * Copyright (C) 2001-2003 Andreas Gruenbacher <agruen@suse.de>
  10 *
  11 * Fix by Harrison Xing <harrison@mountainviewdata.com>.
  12 * Extended attributes for symlinks and special files added per
  13 *  suggestion of Luka Renko <luka.renko@hermes.si>.
  14 * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
  15 *  Red Hat Inc.
  16 *
  17 * This program is free software; you can redistribute it and/or modify
  18 * it under the terms of the GNU General Public License version 2 as
  19 * published by the Free Software Foundation.
  20 */
  21#include <linux/rwsem.h>
  22#include <linux/f2fs_fs.h>
  23#include <linux/security.h>
  24#include "f2fs.h"
  25#include "xattr.h"
  26
  27static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
  28                size_t list_size, const char *name, size_t name_len, int type)
  29{
  30        struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
  31        int total_len, prefix_len = 0;
  32        const char *prefix = NULL;
  33
  34        switch (type) {
  35        case F2FS_XATTR_INDEX_USER:
  36                if (!test_opt(sbi, XATTR_USER))
  37                        return -EOPNOTSUPP;
  38                prefix = XATTR_USER_PREFIX;
  39                prefix_len = XATTR_USER_PREFIX_LEN;
  40                break;
  41        case F2FS_XATTR_INDEX_TRUSTED:
  42                if (!capable(CAP_SYS_ADMIN))
  43                        return -EPERM;
  44                prefix = XATTR_TRUSTED_PREFIX;
  45                prefix_len = XATTR_TRUSTED_PREFIX_LEN;
  46                break;
  47        case F2FS_XATTR_INDEX_SECURITY:
  48                prefix = XATTR_SECURITY_PREFIX;
  49                prefix_len = XATTR_SECURITY_PREFIX_LEN;
  50                break;
  51        default:
  52                return -EINVAL;
  53        }
  54
  55        total_len = prefix_len + name_len + 1;
  56        if (list && total_len <= list_size) {
  57                memcpy(list, prefix, prefix_len);
  58                memcpy(list + prefix_len, name, name_len);
  59                list[prefix_len + name_len] = '\0';
  60        }
  61        return total_len;
  62}
  63
  64static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name,
  65                void *buffer, size_t size, int type)
  66{
  67        struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
  68
  69        switch (type) {
  70        case F2FS_XATTR_INDEX_USER:
  71                if (!test_opt(sbi, XATTR_USER))
  72                        return -EOPNOTSUPP;
  73                break;
  74        case F2FS_XATTR_INDEX_TRUSTED:
  75                if (!capable(CAP_SYS_ADMIN))
  76                        return -EPERM;
  77                break;
  78        case F2FS_XATTR_INDEX_SECURITY:
  79                break;
  80        default:
  81                return -EINVAL;
  82        }
  83        if (strcmp(name, "") == 0)
  84                return -EINVAL;
  85        return f2fs_getxattr(dentry->d_inode, type, name, buffer, size);
  86}
  87
  88static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
  89                const void *value, size_t size, int flags, int type)
  90{
  91        struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
  92
  93        switch (type) {
  94        case F2FS_XATTR_INDEX_USER:
  95                if (!test_opt(sbi, XATTR_USER))
  96                        return -EOPNOTSUPP;
  97                break;
  98        case F2FS_XATTR_INDEX_TRUSTED:
  99                if (!capable(CAP_SYS_ADMIN))
 100                        return -EPERM;
 101                break;
 102        case F2FS_XATTR_INDEX_SECURITY:
 103                break;
 104        default:
 105                return -EINVAL;
 106        }
 107        if (strcmp(name, "") == 0)
 108                return -EINVAL;
 109
 110        return f2fs_setxattr(dentry->d_inode, type, name, value, size, NULL);
 111}
 112
 113static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
 114                size_t list_size, const char *name, size_t name_len, int type)
 115{
 116        const char *xname = F2FS_SYSTEM_ADVISE_PREFIX;
 117        size_t size;
 118
 119        if (type != F2FS_XATTR_INDEX_ADVISE)
 120                return 0;
 121
 122        size = strlen(xname) + 1;
 123        if (list && size <= list_size)
 124                memcpy(list, xname, size);
 125        return size;
 126}
 127
 128static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name,
 129                void *buffer, size_t size, int type)
 130{
 131        struct inode *inode = dentry->d_inode;
 132
 133        if (strcmp(name, "") != 0)
 134                return -EINVAL;
 135
 136        *((char *)buffer) = F2FS_I(inode)->i_advise;
 137        return sizeof(char);
 138}
 139
 140static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name,
 141                const void *value, size_t size, int flags, int type)
 142{
 143        struct inode *inode = dentry->d_inode;
 144
 145        if (strcmp(name, "") != 0)
 146                return -EINVAL;
 147        if (!inode_owner_or_capable(inode))
 148                return -EPERM;
 149        if (value == NULL)
 150                return -EINVAL;
 151
 152        F2FS_I(inode)->i_advise |= *(char *)value;
 153        return 0;
 154}
 155
 156#ifdef CONFIG_F2FS_FS_SECURITY
 157static int __f2fs_setxattr(struct inode *inode, int name_index,
 158                        const char *name, const void *value, size_t value_len,
 159                        struct page *ipage);
 160static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
 161                void *page)
 162{
 163        const struct xattr *xattr;
 164        int err = 0;
 165
 166        for (xattr = xattr_array; xattr->name != NULL; xattr++) {
 167                err = __f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
 168                                xattr->name, xattr->value,
 169                                xattr->value_len, (struct page *)page);
 170                if (err < 0)
 171                        break;
 172        }
 173        return err;
 174}
 175
 176int f2fs_init_security(struct inode *inode, struct inode *dir,
 177                                const struct qstr *qstr, struct page *ipage)
 178{
 179        return security_inode_init_security(inode, dir, qstr,
 180                                &f2fs_initxattrs, ipage);
 181}
 182#endif
 183
 184const struct xattr_handler f2fs_xattr_user_handler = {
 185        .prefix = XATTR_USER_PREFIX,
 186        .flags  = F2FS_XATTR_INDEX_USER,
 187        .list   = f2fs_xattr_generic_list,
 188        .get    = f2fs_xattr_generic_get,
 189        .set    = f2fs_xattr_generic_set,
 190};
 191
 192const struct xattr_handler f2fs_xattr_trusted_handler = {
 193        .prefix = XATTR_TRUSTED_PREFIX,
 194        .flags  = F2FS_XATTR_INDEX_TRUSTED,
 195        .list   = f2fs_xattr_generic_list,
 196        .get    = f2fs_xattr_generic_get,
 197        .set    = f2fs_xattr_generic_set,
 198};
 199
 200const struct xattr_handler f2fs_xattr_advise_handler = {
 201        .prefix = F2FS_SYSTEM_ADVISE_PREFIX,
 202        .flags  = F2FS_XATTR_INDEX_ADVISE,
 203        .list   = f2fs_xattr_advise_list,
 204        .get    = f2fs_xattr_advise_get,
 205        .set    = f2fs_xattr_advise_set,
 206};
 207
 208const struct xattr_handler f2fs_xattr_security_handler = {
 209        .prefix = XATTR_SECURITY_PREFIX,
 210        .flags  = F2FS_XATTR_INDEX_SECURITY,
 211        .list   = f2fs_xattr_generic_list,
 212        .get    = f2fs_xattr_generic_get,
 213        .set    = f2fs_xattr_generic_set,
 214};
 215
 216static const struct xattr_handler *f2fs_xattr_handler_map[] = {
 217        [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
 218#ifdef CONFIG_F2FS_FS_POSIX_ACL
 219        [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &f2fs_xattr_acl_access_handler,
 220        [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
 221#endif
 222        [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
 223#ifdef CONFIG_F2FS_FS_SECURITY
 224        [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler,
 225#endif
 226        [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
 227};
 228
 229const struct xattr_handler *f2fs_xattr_handlers[] = {
 230        &f2fs_xattr_user_handler,
 231#ifdef CONFIG_F2FS_FS_POSIX_ACL
 232        &f2fs_xattr_acl_access_handler,
 233        &f2fs_xattr_acl_default_handler,
 234#endif
 235        &f2fs_xattr_trusted_handler,
 236#ifdef CONFIG_F2FS_FS_SECURITY
 237        &f2fs_xattr_security_handler,
 238#endif
 239        &f2fs_xattr_advise_handler,
 240        NULL,
 241};
 242
 243static inline const struct xattr_handler *f2fs_xattr_handler(int name_index)
 244{
 245        const struct xattr_handler *handler = NULL;
 246
 247        if (name_index > 0 && name_index < ARRAY_SIZE(f2fs_xattr_handler_map))
 248                handler = f2fs_xattr_handler_map[name_index];
 249        return handler;
 250}
 251
 252static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int name_index,
 253                                        size_t name_len, const char *name)
 254{
 255        struct f2fs_xattr_entry *entry;
 256
 257        list_for_each_xattr(entry, base_addr) {
 258                if (entry->e_name_index != name_index)
 259                        continue;
 260                if (entry->e_name_len != name_len)
 261                        continue;
 262                if (!memcmp(entry->e_name, name, name_len))
 263                        break;
 264        }
 265        return entry;
 266}
 267
 268static void *read_all_xattrs(struct inode *inode, struct page *ipage)
 269{
 270        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
 271        struct f2fs_xattr_header *header;
 272        size_t size = PAGE_SIZE, inline_size = 0;
 273        void *txattr_addr;
 274
 275        inline_size = inline_xattr_size(inode);
 276
 277        txattr_addr = kzalloc(inline_size + size, GFP_KERNEL);
 278        if (!txattr_addr)
 279                return NULL;
 280
 281        /* read from inline xattr */
 282        if (inline_size) {
 283                struct page *page = NULL;
 284                void *inline_addr;
 285
 286                if (ipage) {
 287                        inline_addr = inline_xattr_addr(ipage);
 288                } else {
 289                        page = get_node_page(sbi, inode->i_ino);
 290                        if (IS_ERR(page))
 291                                goto fail;
 292                        inline_addr = inline_xattr_addr(page);
 293                }
 294                memcpy(txattr_addr, inline_addr, inline_size);
 295                f2fs_put_page(page, 1);
 296        }
 297
 298        /* read from xattr node block */
 299        if (F2FS_I(inode)->i_xattr_nid) {
 300                struct page *xpage;
 301                void *xattr_addr;
 302
 303                /* The inode already has an extended attribute block. */
 304                xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
 305                if (IS_ERR(xpage))
 306                        goto fail;
 307
 308                xattr_addr = page_address(xpage);
 309                memcpy(txattr_addr + inline_size, xattr_addr, PAGE_SIZE);
 310                f2fs_put_page(xpage, 1);
 311        }
 312
 313        header = XATTR_HDR(txattr_addr);
 314
 315        /* never been allocated xattrs */
 316        if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
 317                header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
 318                header->h_refcount = cpu_to_le32(1);
 319        }
 320        return txattr_addr;
 321fail:
 322        kzfree(txattr_addr);
 323        return NULL;
 324}
 325
 326static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
 327                                void *txattr_addr, struct page *ipage)
 328{
 329        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
 330        size_t inline_size = 0;
 331        void *xattr_addr;
 332        struct page *xpage;
 333        nid_t new_nid = 0;
 334        int err;
 335
 336        inline_size = inline_xattr_size(inode);
 337
 338        if (hsize > inline_size && !F2FS_I(inode)->i_xattr_nid)
 339                if (!alloc_nid(sbi, &new_nid))
 340                        return -ENOSPC;
 341
 342        /* write to inline xattr */
 343        if (inline_size) {
 344                struct page *page = NULL;
 345                void *inline_addr;
 346
 347                if (ipage) {
 348                        inline_addr = inline_xattr_addr(ipage);
 349                } else {
 350                        page = get_node_page(sbi, inode->i_ino);
 351                        if (IS_ERR(page)) {
 352                                alloc_nid_failed(sbi, new_nid);
 353                                return PTR_ERR(page);
 354                        }
 355                        inline_addr = inline_xattr_addr(page);
 356                }
 357                memcpy(inline_addr, txattr_addr, inline_size);
 358                f2fs_put_page(page, 1);
 359
 360                /* no need to use xattr node block */
 361                if (hsize <= inline_size) {
 362                        err = truncate_xattr_node(inode, ipage);
 363                        alloc_nid_failed(sbi, new_nid);
 364                        return err;
 365                }
 366        }
 367
 368        /* write to xattr node block */
 369        if (F2FS_I(inode)->i_xattr_nid) {
 370                xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
 371                if (IS_ERR(xpage)) {
 372                        alloc_nid_failed(sbi, new_nid);
 373                        return PTR_ERR(xpage);
 374                }
 375                f2fs_bug_on(new_nid);
 376        } else {
 377                struct dnode_of_data dn;
 378                set_new_dnode(&dn, inode, NULL, NULL, new_nid);
 379                xpage = new_node_page(&dn, XATTR_NODE_OFFSET, ipage);
 380                if (IS_ERR(xpage)) {
 381                        alloc_nid_failed(sbi, new_nid);
 382                        return PTR_ERR(xpage);
 383                }
 384                alloc_nid_done(sbi, new_nid);
 385        }
 386
 387        xattr_addr = page_address(xpage);
 388        memcpy(xattr_addr, txattr_addr + inline_size, PAGE_SIZE -
 389                                                sizeof(struct node_footer));
 390        set_page_dirty(xpage);
 391        f2fs_put_page(xpage, 1);
 392
 393        /* need to checkpoint during fsync */
 394        F2FS_I(inode)->xattr_ver = cur_cp_version(F2FS_CKPT(sbi));
 395        return 0;
 396}
 397
 398int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
 399                void *buffer, size_t buffer_size)
 400{
 401        struct f2fs_xattr_entry *entry;
 402        void *base_addr;
 403        int error = 0;
 404        size_t value_len, name_len;
 405
 406        if (name == NULL)
 407                return -EINVAL;
 408        name_len = strlen(name);
 409
 410        base_addr = read_all_xattrs(inode, NULL);
 411        if (!base_addr)
 412                return -ENOMEM;
 413
 414        entry = __find_xattr(base_addr, name_index, name_len, name);
 415        if (IS_XATTR_LAST_ENTRY(entry)) {
 416                error = -ENODATA;
 417                goto cleanup;
 418        }
 419
 420        value_len = le16_to_cpu(entry->e_value_size);
 421
 422        if (buffer && value_len > buffer_size) {
 423                error = -ERANGE;
 424                goto cleanup;
 425        }
 426
 427        if (buffer) {
 428                char *pval = entry->e_name + entry->e_name_len;
 429                memcpy(buffer, pval, value_len);
 430        }
 431        error = value_len;
 432
 433cleanup:
 434        kzfree(base_addr);
 435        return error;
 436}
 437
 438ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 439{
 440        struct inode *inode = dentry->d_inode;
 441        struct f2fs_xattr_entry *entry;
 442        void *base_addr;
 443        int error = 0;
 444        size_t rest = buffer_size;
 445
 446        base_addr = read_all_xattrs(inode, NULL);
 447        if (!base_addr)
 448                return -ENOMEM;
 449
 450        list_for_each_xattr(entry, base_addr) {
 451                const struct xattr_handler *handler =
 452                        f2fs_xattr_handler(entry->e_name_index);
 453                size_t size;
 454
 455                if (!handler)
 456                        continue;
 457
 458                size = handler->list(dentry, buffer, rest, entry->e_name,
 459                                entry->e_name_len, handler->flags);
 460                if (buffer && size > rest) {
 461                        error = -ERANGE;
 462                        goto cleanup;
 463                }
 464
 465                if (buffer)
 466                        buffer += size;
 467                rest -= size;
 468        }
 469        error = buffer_size - rest;
 470cleanup:
 471        kzfree(base_addr);
 472        return error;
 473}
 474
 475static int __f2fs_setxattr(struct inode *inode, int name_index,
 476                        const char *name, const void *value, size_t value_len,
 477                        struct page *ipage)
 478{
 479        struct f2fs_inode_info *fi = F2FS_I(inode);
 480        struct f2fs_xattr_entry *here, *last;
 481        void *base_addr;
 482        int found, newsize;
 483        size_t name_len;
 484        __u32 new_hsize;
 485        int error = -ENOMEM;
 486
 487        if (name == NULL)
 488                return -EINVAL;
 489
 490        if (value == NULL)
 491                value_len = 0;
 492
 493        name_len = strlen(name);
 494
 495        if (name_len > F2FS_NAME_LEN || value_len > MAX_VALUE_LEN(inode))
 496                return -ERANGE;
 497
 498        base_addr = read_all_xattrs(inode, ipage);
 499        if (!base_addr)
 500                goto exit;
 501
 502        /* find entry with wanted name. */
 503        here = __find_xattr(base_addr, name_index, name_len, name);
 504
 505        found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1;
 506        last = here;
 507
 508        while (!IS_XATTR_LAST_ENTRY(last))
 509                last = XATTR_NEXT_ENTRY(last);
 510
 511        newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) +
 512                        name_len + value_len);
 513
 514        /* 1. Check space */
 515        if (value) {
 516                int free;
 517                /*
 518                 * If value is NULL, it is remove operation.
 519                 * In case of update operation, we caculate free.
 520                 */
 521                free = MIN_OFFSET(inode) - ((char *)last - (char *)base_addr);
 522                if (found)
 523                        free = free + ENTRY_SIZE(here);
 524
 525                if (free < newsize) {
 526                        error = -ENOSPC;
 527                        goto exit;
 528                }
 529        }
 530
 531        /* 2. Remove old entry */
 532        if (found) {
 533                /*
 534                 * If entry is found, remove old entry.
 535                 * If not found, remove operation is not needed.
 536                 */
 537                struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
 538                int oldsize = ENTRY_SIZE(here);
 539
 540                memmove(here, next, (char *)last - (char *)next);
 541                last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
 542                memset(last, 0, oldsize);
 543        }
 544
 545        new_hsize = (char *)last - (char *)base_addr;
 546
 547        /* 3. Write new entry */
 548        if (value) {
 549                char *pval;
 550                /*
 551                 * Before we come here, old entry is removed.
 552                 * We just write new entry.
 553                 */
 554                memset(last, 0, newsize);
 555                last->e_name_index = name_index;
 556                last->e_name_len = name_len;
 557                memcpy(last->e_name, name, name_len);
 558                pval = last->e_name + name_len;
 559                memcpy(pval, value, value_len);
 560                last->e_value_size = cpu_to_le16(value_len);
 561                new_hsize += newsize;
 562        }
 563
 564        error = write_all_xattrs(inode, new_hsize, base_addr, ipage);
 565        if (error)
 566                goto exit;
 567
 568        if (is_inode_flag_set(fi, FI_ACL_MODE)) {
 569                inode->i_mode = fi->i_acl_mode;
 570                inode->i_ctime = CURRENT_TIME;
 571                clear_inode_flag(fi, FI_ACL_MODE);
 572        }
 573
 574        if (ipage)
 575                update_inode(inode, ipage);
 576        else
 577                update_inode_page(inode);
 578exit:
 579        kzfree(base_addr);
 580        return error;
 581}
 582
 583int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
 584                        const void *value, size_t value_len, struct page *ipage)
 585{
 586        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
 587        int err;
 588
 589        f2fs_balance_fs(sbi);
 590
 591        f2fs_lock_op(sbi);
 592        err = __f2fs_setxattr(inode, name_index, name, value, value_len, ipage);
 593        f2fs_unlock_op(sbi);
 594
 595        return err;
 596}
 597