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