Merge branch 'work.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 25 Oct 2018 19:55:31 +0000 (12:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 25 Oct 2018 19:55:31 +0000 (12:55 -0700)
Pull more ->lookup() cleanups from Al Viro:
 "Some ->lookup() instances are still overcomplicating the life
  for themselves, open-coding the stuff that would be handled by
  d_splice_alias() just fine.

  Simplify a couple of such cases caught this cycle and document
  d_splice_alias() intended use"

* 'work.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  Document d_splice_alias() calling conventions for ->lookup() users.
  simplify btrfs_lookup()
  clean erofs_lookup()

1  2 
fs/btrfs/inode.c

diff --combined fs/btrfs/inode.c
index f22f77172c5ff5299b37aa8e10be770929c61a44,fb688c4aa34fc9100a3595a57b099b86dc1c5e39..181c58b231103e5a7381be49cddc10c2faf3fdc5
@@@ -64,6 -64,7 +64,6 @@@ static const struct inode_operations bt
  static const struct inode_operations btrfs_special_inode_operations;
  static const struct inode_operations btrfs_file_inode_operations;
  static const struct address_space_operations btrfs_aops;
 -static const struct address_space_operations btrfs_symlink_aops;
  static const struct file_operations btrfs_dir_file_operations;
  static const struct extent_io_ops btrfs_extent_io_ops;
  
@@@ -1270,7 -1271,7 +1270,7 @@@ static noinline int run_delalloc_nocow(
        u64 disk_num_bytes;
        u64 ram_bytes;
        int extent_type;
 -      int ret, err;
 +      int ret;
        int type;
        int nocow;
        int check_prev = 1;
@@@ -1402,8 -1403,11 +1402,8 @@@ next_slot
                         * if there are pending snapshots for this root,
                         * we fall into common COW way.
                         */
 -                      if (!nolock) {
 -                              err = btrfs_start_write_no_snapshotting(root);
 -                              if (!err)
 -                                      goto out_check;
 -                      }
 +                      if (!nolock && atomic_read(&root->snapshot_force_cow))
 +                              goto out_check;
                        /*
                         * force cow if csum exists in the range.
                         * this ensure that csum for a given extent are
                        ret = csum_exist_in_range(fs_info, disk_bytenr,
                                                  num_bytes);
                        if (ret) {
 -                              if (!nolock)
 -                                      btrfs_end_write_no_snapshotting(root);
 -
                                /*
                                 * ret could be -EIO if the above fails to read
                                 * metadata.
                                WARN_ON_ONCE(nolock);
                                goto out_check;
                        }
 -                      if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) {
 -                              if (!nolock)
 -                                      btrfs_end_write_no_snapshotting(root);
 +                      if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr))
                                goto out_check;
 -                      }
                        nocow = 1;
                } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
                        extent_end = found_key.offset +
  out_check:
                if (extent_end <= start) {
                        path->slots[0]++;
 -                      if (!nolock && nocow)
 -                              btrfs_end_write_no_snapshotting(root);
                        if (nocow)
                                btrfs_dec_nocow_writers(fs_info, disk_bytenr);
                        goto next_slot;
                                             end, page_started, nr_written, 1,
                                             NULL);
                        if (ret) {
 -                              if (!nolock && nocow)
 -                                      btrfs_end_write_no_snapshotting(root);
                                if (nocow)
                                        btrfs_dec_nocow_writers(fs_info,
                                                                disk_bytenr);
                                          ram_bytes, BTRFS_COMPRESS_NONE,
                                          BTRFS_ORDERED_PREALLOC);
                        if (IS_ERR(em)) {
 -                              if (!nolock && nocow)
 -                                      btrfs_end_write_no_snapshotting(root);
                                if (nocow)
                                        btrfs_dec_nocow_writers(fs_info,
                                                                disk_bytenr);
                                             EXTENT_CLEAR_DATA_RESV,
                                             PAGE_UNLOCK | PAGE_SET_PRIVATE2);
  
 -              if (!nolock && nocow)
 -                      btrfs_end_write_no_snapshotting(root);
                cur_offset = extent_end;
  
                /*
@@@ -2749,9 -2767,12 +2749,9 @@@ static void relink_file_extents(struct 
        struct btrfs_path *path;
        struct sa_defrag_extent_backref *backref;
        struct sa_defrag_extent_backref *prev = NULL;
 -      struct inode *inode;
        struct rb_node *node;
        int ret;
  
 -      inode = new->inode;
 -
        path = btrfs_alloc_path();
        if (!path)
                return;
@@@ -3467,6 -3488,8 +3467,6 @@@ int btrfs_orphan_cleanup(struct btrfs_r
  
                /* this will do delete_inode and everything for us */
                iput(inode);
 -              if (ret)
 -                      goto out;
        }
        /* release the path since we're done with it */
        btrfs_release_path(path);
@@@ -3732,7 -3755,7 +3732,7 @@@ cache_acl
        case S_IFLNK:
                inode->i_op = &btrfs_symlink_inode_operations;
                inode_nohighmem(inode);
 -              inode->i_mapping->a_ops = &btrfs_symlink_aops;
 +              inode->i_mapping->a_ops = &btrfs_aops;
                break;
        default:
                inode->i_op = &btrfs_special_inode_operations;
@@@ -3904,8 -3927,12 +3904,8 @@@ static int __btrfs_unlink_inode(struct 
        path->leave_spinning = 1;
        di = btrfs_lookup_dir_item(trans, root, path, dir_ino,
                                    name, name_len, -1);
 -      if (IS_ERR(di)) {
 -              ret = PTR_ERR(di);
 -              goto err;
 -      }
 -      if (!di) {
 -              ret = -ENOENT;
 +      if (IS_ERR_OR_NULL(di)) {
 +              ret = di ? PTR_ERR(di) : -ENOENT;
                goto err;
        }
        leaf = path->nodes[0];
@@@ -4065,7 -4092,10 +4065,7 @@@ static int btrfs_unlink_subvol(struct b
        di = btrfs_lookup_dir_item(trans, root, path, dir_ino,
                                   name, name_len, -1);
        if (IS_ERR_OR_NULL(di)) {
 -              if (!di)
 -                      ret = -ENOENT;
 -              else
 -                      ret = PTR_ERR(di);
 +              ret = di ? PTR_ERR(di) : -ENOENT;
                goto out;
        }
  
@@@ -4257,17 -4287,18 +4257,17 @@@ int btrfs_delete_subvolume(struct inod
         * again is not run concurrently.
         */
        spin_lock(&dest->root_item_lock);
 -      root_flags = btrfs_root_flags(&dest->root_item);
 -      if (dest->send_in_progress == 0) {
 -              btrfs_set_root_flags(&dest->root_item,
 -                              root_flags | BTRFS_ROOT_SUBVOL_DEAD);
 -              spin_unlock(&dest->root_item_lock);
 -      } else {
 +      if (dest->send_in_progress) {
                spin_unlock(&dest->root_item_lock);
                btrfs_warn(fs_info,
                           "attempt to delete subvolume %llu during send",
                           dest->root_key.objectid);
                return -EPERM;
        }
 +      root_flags = btrfs_root_flags(&dest->root_item);
 +      btrfs_set_root_flags(&dest->root_item,
 +                           root_flags | BTRFS_ROOT_SUBVOL_DEAD);
 +      spin_unlock(&dest->root_item_lock);
  
        down_write(&fs_info->subvol_sem);
  
@@@ -4713,7 -4744,7 +4713,7 @@@ delete
                                btrfs_abort_transaction(trans, ret);
                                break;
                        }
 -                      if (btrfs_should_throttle_delayed_refs(trans, fs_info))
 +                      if (btrfs_should_throttle_delayed_refs(trans))
                                btrfs_async_run_delayed_refs(fs_info,
                                        trans->delayed_ref_updates * 2,
                                        trans->transid, 0);
                                                         extent_num_bytes)) {
                                        should_end = true;
                                }
 -                              if (btrfs_should_throttle_delayed_refs(trans,
 -                                                                     fs_info))
 +                              if (btrfs_should_throttle_delayed_refs(trans))
                                        should_throttle = true;
                        }
                }
@@@ -5220,10 -5252,10 +5220,10 @@@ static void evict_inode_truncate_pages(
        truncate_inode_pages_final(&inode->i_data);
  
        write_lock(&map_tree->lock);
 -      while (!RB_EMPTY_ROOT(&map_tree->map)) {
 +      while (!RB_EMPTY_ROOT(&map_tree->map.rb_root)) {
                struct extent_map *em;
  
 -              node = rb_first(&map_tree->map);
 +              node = rb_first_cached(&map_tree->map);
                em = rb_entry(node, struct extent_map, rb_node);
                clear_bit(EXTENT_FLAG_PINNED, &em->flags);
                clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
  }
  
  static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root,
 -                                                      struct btrfs_block_rsv *rsv,
 -                                                      u64 min_size)
 +                                                      struct btrfs_block_rsv *rsv)
  {
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
                struct btrfs_trans_handle *trans;
                int ret;
  
 -              ret = btrfs_block_rsv_refill(root, rsv, min_size,
 +              ret = btrfs_block_rsv_refill(root, rsv, rsv->size,
                                             BTRFS_RESERVE_FLUSH_LIMIT);
  
                if (ret && ++failures > 2) {
                 * Try to steal from the global reserve if there is space for
                 * it.
                 */
 -              if (!btrfs_check_space_for_delayed_refs(trans, fs_info) &&
 -                  !btrfs_block_rsv_migrate(global_rsv, rsv, min_size, 0))
 +              if (!btrfs_check_space_for_delayed_refs(trans) &&
 +                  !btrfs_block_rsv_migrate(global_rsv, rsv, rsv->size, false))
                        return trans;
  
                /* If not, commit and try again. */
@@@ -5335,6 -5368,7 +5335,6 @@@ void btrfs_evict_inode(struct inode *in
        struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_block_rsv *rsv;
 -      u64 min_size;
        int ret;
  
        trace_btrfs_inode_evict(inode);
                return;
        }
  
 -      min_size = btrfs_calc_trunc_metadata_size(fs_info, 1);
 -
        evict_inode_truncate_pages(inode);
  
        if (inode->i_nlink &&
  
        if (is_bad_inode(inode))
                goto no_delete;
 -      /* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */
 -      if (!special_file(inode->i_mode))
 -              btrfs_wait_ordered_range(inode, 0, (u64)-1);
  
        btrfs_free_io_failure_record(BTRFS_I(inode), 0, (u64)-1);
  
        rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP);
        if (!rsv)
                goto no_delete;
 -      rsv->size = min_size;
 +      rsv->size = btrfs_calc_trunc_metadata_size(fs_info, 1);
        rsv->failfast = 1;
  
        btrfs_i_size_write(BTRFS_I(inode), 0);
  
        while (1) {
 -              trans = evict_refill_and_join(root, rsv, min_size);
 +              trans = evict_refill_and_join(root, rsv);
                if (IS_ERR(trans))
                        goto free_rsv;
  
         * If it turns out that we are dropping too many of these, we might want
         * to add a mechanism for retrying these after a commit.
         */
 -      trans = evict_refill_and_join(root, rsv, min_size);
 +      trans = evict_refill_and_join(root, rsv);
        if (!IS_ERR(trans)) {
                trans->block_rsv = rsv;
                btrfs_orphan_del(trans, BTRFS_I(inode));
@@@ -5449,8 -5488,12 +5449,8 @@@ static int btrfs_inode_by_name(struct i
  
        di = btrfs_lookup_dir_item(NULL, root, path, btrfs_ino(BTRFS_I(dir)),
                        name, namelen, 0);
 -      if (!di) {
 -              ret = -ENOENT;
 -              goto out;
 -      }
 -      if (IS_ERR(di)) {
 -              ret = PTR_ERR(di);
 +      if (IS_ERR_OR_NULL(di)) {
 +              ret = di ? PTR_ERR(di) : -ENOENT;
                goto out;
        }
  
@@@ -5764,16 -5807,10 +5764,10 @@@ static int btrfs_dentry_delete(const st
  static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
                                   unsigned int flags)
  {
-       struct inode *inode;
-       inode = btrfs_lookup_dentry(dir, dentry);
-       if (IS_ERR(inode)) {
-               if (PTR_ERR(inode) == -ENOENT)
-                       inode = NULL;
-               else
-                       return ERR_CAST(inode);
-       }
+       struct inode *inode = btrfs_lookup_dentry(dir, dentry);
  
+       if (inode == ERR_PTR(-ENOENT))
+               inode = NULL;
        return d_splice_alias(inode, dentry);
  }
  
@@@ -6364,7 -6401,8 +6358,7 @@@ int btrfs_add_link(struct btrfs_trans_h
        if (ret)
                return ret;
  
 -      ret = btrfs_insert_dir_item(trans, root, name, name_len,
 -                                  parent_inode, &key,
 +      ret = btrfs_insert_dir_item(trans, name, name_len, parent_inode, &key,
                                    btrfs_inode_type(&inode->vfs_inode), index);
        if (ret == -EEXIST || ret == -EOVERFLOW)
                goto fail_dir_item;
@@@ -6557,7 -6595,7 +6551,7 @@@ static int btrfs_link(struct dentry *ol
        int drop_inode = 0;
  
        /* do not allow sys_link's with other subvols of the same device */
 -      if (root->objectid != BTRFS_I(inode)->root->objectid)
 +      if (root->root_key.objectid != BTRFS_I(inode)->root->root_key.objectid)
                return -EXDEV;
  
        if (inode->i_nlink >= BTRFS_LINK_MAX)
                drop_inode = 1;
        } else {
                struct dentry *parent = dentry->d_parent;
 +              int ret;
 +
                err = btrfs_update_inode(trans, root, inode);
                if (err)
                        goto fail;
                                goto fail;
                }
                d_instantiate(dentry, inode);
 -              btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent);
 +              ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent,
 +                                       true, NULL);
 +              if (ret == BTRFS_NEED_TRANS_COMMIT) {
 +                      err = btrfs_commit_transaction(trans);
 +                      trans = NULL;
 +              }
        }
  
  fail:
@@@ -6750,9 -6781,9 +6744,9 @@@ static noinline int uncompress_inline(s
   * This also copies inline extents directly into the page.
   */
  struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
 -              struct page *page,
 -          size_t pg_offset, u64 start, u64 len,
 -              int create)
 +                                  struct page *page,
 +                                  size_t pg_offset, u64 start, u64 len,
 +                                  int create)
  {
        struct btrfs_fs_info *fs_info = inode->root->fs_info;
        int ret;
        em->len = (u64)-1;
        em->block_len = (u64)-1;
  
 +      path = btrfs_alloc_path();
        if (!path) {
 -              path = btrfs_alloc_path();
 -              if (!path) {
 -                      err = -ENOMEM;
 -                      goto out;
 -              }
 -              /*
 -               * Chances are we'll be called again, so go ahead and do
 -               * readahead
 -               */
 -              path->reada = READA_FORWARD;
 +              err = -ENOMEM;
 +              goto out;
        }
  
 +      /* Chances are we'll be called again, so go ahead and do readahead */
 +      path->reada = READA_FORWARD;
 +
 +      /*
 +       * Unless we're going to uncompress the inline extent, no sleep would
 +       * happen.
 +       */
 +      path->leave_spinning = 1;
 +
        ret = btrfs_lookup_file_extent(NULL, root, path, objectid, start, 0);
        if (ret < 0) {
                err = ret;
@@@ -6913,8 -6942,6 +6907,8 @@@ next
                em->orig_block_len = em->len;
                em->orig_start = em->start;
                ptr = btrfs_file_extent_inline_start(item) + extent_offset;
 +
 +              btrfs_set_path_blocking(path);
                if (!PageUptodate(page)) {
                        if (btrfs_file_extent_compression(leaf, item) !=
                            BTRFS_COMPRESS_NONE) {
@@@ -6962,10 -6989,10 +6956,10 @@@ insert
        err = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len);
        write_unlock(&em_tree->lock);
  out:
 +      btrfs_free_path(path);
  
        trace_btrfs_get_extent(root, inode, em);
  
 -      btrfs_free_path(path);
        if (err) {
                free_extent_map(em);
                return ERR_PTR(err);
@@@ -8998,7 -9025,7 +8992,7 @@@ static int btrfs_truncate(struct inode 
  
        /* Migrate the slack space for the truncate to our reserve */
        ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv,
 -                                    min_size, 0);
 +                                    min_size, false);
        BUG_ON(ret);
  
        /*
  
                btrfs_block_rsv_release(fs_info, rsv, -1);
                ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv,
 -                                            rsv, min_size, 0);
 +                                            rsv, min_size, false);
                BUG_ON(ret);    /* shouldn't happen */
                trans->block_rsv = rsv;
        }
@@@ -9355,21 -9382,14 +9349,21 @@@ static int btrfs_rename_exchange(struc
        u64 new_idx = 0;
        u64 root_objectid;
        int ret;
 -      int ret2;
        bool root_log_pinned = false;
        bool dest_log_pinned = false;
 +      struct btrfs_log_ctx ctx_root;
 +      struct btrfs_log_ctx ctx_dest;
 +      bool sync_log_root = false;
 +      bool sync_log_dest = false;
 +      bool commit_transaction = false;
  
        /* we only allow rename subvolume link between subvolumes */
        if (old_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest)
                return -EXDEV;
  
 +      btrfs_init_log_ctx(&ctx_root, old_inode);
 +      btrfs_init_log_ctx(&ctx_dest, new_inode);
 +
        /* close the race window with snapshot create/destroy ioctl */
        if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
                down_read(&fs_info->subvol_sem);
  
        if (root_log_pinned) {
                parent = new_dentry->d_parent;
 -              btrfs_log_new_name(trans, BTRFS_I(old_inode), BTRFS_I(old_dir),
 -                              parent);
 +              ret = btrfs_log_new_name(trans, BTRFS_I(old_inode),
 +                                       BTRFS_I(old_dir), parent,
 +                                       false, &ctx_root);
 +              if (ret == BTRFS_NEED_LOG_SYNC)
 +                      sync_log_root = true;
 +              else if (ret == BTRFS_NEED_TRANS_COMMIT)
 +                      commit_transaction = true;
 +              ret = 0;
                btrfs_end_log_trans(root);
                root_log_pinned = false;
        }
        if (dest_log_pinned) {
 -              parent = old_dentry->d_parent;
 -              btrfs_log_new_name(trans, BTRFS_I(new_inode), BTRFS_I(new_dir),
 -                              parent);
 +              if (!commit_transaction) {
 +                      parent = old_dentry->d_parent;
 +                      ret = btrfs_log_new_name(trans, BTRFS_I(new_inode),
 +                                               BTRFS_I(new_dir), parent,
 +                                               false, &ctx_dest);
 +                      if (ret == BTRFS_NEED_LOG_SYNC)
 +                              sync_log_dest = true;
 +                      else if (ret == BTRFS_NEED_TRANS_COMMIT)
 +                              commit_transaction = true;
 +                      ret = 0;
 +              }
                btrfs_end_log_trans(dest);
                dest_log_pinned = false;
        }
@@@ -9571,26 -9577,8 +9565,26 @@@ out_fail
                        dest_log_pinned = false;
                }
        }
 -      ret2 = btrfs_end_transaction(trans);
 -      ret = ret ? ret : ret2;
 +      if (!ret && sync_log_root && !commit_transaction) {
 +              ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root,
 +                                   &ctx_root);
 +              if (ret)
 +                      commit_transaction = true;
 +      }
 +      if (!ret && sync_log_dest && !commit_transaction) {
 +              ret = btrfs_sync_log(trans, BTRFS_I(new_inode)->root,
 +                                   &ctx_dest);
 +              if (ret)
 +                      commit_transaction = true;
 +      }
 +      if (commit_transaction) {
 +              ret = btrfs_commit_transaction(trans);
 +      } else {
 +              int ret2;
 +
 +              ret2 = btrfs_end_transaction(trans);
 +              ret = ret ? ret : ret2;
 +      }
  out_notrans:
        if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
                up_read(&fs_info->subvol_sem);
@@@ -9667,9 -9655,6 +9661,9 @@@ static int btrfs_rename(struct inode *o
        int ret;
        u64 old_ino = btrfs_ino(BTRFS_I(old_inode));
        bool log_pinned = false;
 +      struct btrfs_log_ctx ctx;
 +      bool sync_log = false;
 +      bool commit_transaction = false;
  
        if (btrfs_ino(BTRFS_I(new_dir)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)
                return -EPERM;
        if (log_pinned) {
                struct dentry *parent = new_dentry->d_parent;
  
 -              btrfs_log_new_name(trans, BTRFS_I(old_inode), BTRFS_I(old_dir),
 -                              parent);
 +              btrfs_init_log_ctx(&ctx, old_inode);
 +              ret = btrfs_log_new_name(trans, BTRFS_I(old_inode),
 +                                       BTRFS_I(old_dir), parent,
 +                                       false, &ctx);
 +              if (ret == BTRFS_NEED_LOG_SYNC)
 +                      sync_log = true;
 +              else if (ret == BTRFS_NEED_TRANS_COMMIT)
 +                      commit_transaction = true;
 +              ret = 0;
                btrfs_end_log_trans(root);
                log_pinned = false;
        }
@@@ -9872,19 -9850,7 +9866,19 @@@ out_fail
                btrfs_end_log_trans(root);
                log_pinned = false;
        }
 -      btrfs_end_transaction(trans);
 +      if (!ret && sync_log) {
 +              ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root, &ctx);
 +              if (ret)
 +                      commit_transaction = true;
 +      }
 +      if (commit_transaction) {
 +              ret = btrfs_commit_transaction(trans);
 +      } else {
 +              int ret2;
 +
 +              ret2 = btrfs_end_transaction(trans);
 +              ret = ret ? ret : ret2;
 +      }
  out_notrans:
        if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
                up_read(&fs_info->subvol_sem);
@@@ -10168,7 -10134,7 +10162,7 @@@ static int btrfs_symlink(struct inode *
  
        inode->i_op = &btrfs_symlink_inode_operations;
        inode_nohighmem(inode);
 -      inode->i_mapping->a_ops = &btrfs_symlink_aops;
 +      inode->i_mapping->a_ops = &btrfs_aops;
        inode_set_bytes(inode, name_len);
        btrfs_i_size_write(BTRFS_I(inode), name_len);
        err = btrfs_update_inode(trans, root, inode);
@@@ -10544,6 -10510,13 +10538,6 @@@ static const struct address_space_opera
        .error_remove_page = generic_error_remove_page,
  };
  
 -static const struct address_space_operations btrfs_symlink_aops = {
 -      .readpage       = btrfs_readpage,
 -      .writepage      = btrfs_writepage,
 -      .invalidatepage = btrfs_invalidatepage,
 -      .releasepage    = btrfs_releasepage,
 -};
 -
  static const struct inode_operations btrfs_file_inode_operations = {
        .getattr        = btrfs_getattr,
        .setattr        = btrfs_setattr,