diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 603 |
1 files changed, 310 insertions, 293 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7acbd2cf6192..0a6902555e65 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -33,7 +33,6 @@ #include <linux/namei.h> #include <linux/swap.h> #include <linux/writeback.h> -#include <linux/statfs.h> #include <linux/compat.h> #include <linux/bit_spinlock.h> #include <linux/security.h> @@ -216,6 +215,7 @@ static int check_flags(unsigned int flags) static int btrfs_ioctl_setflags(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_inode *ip = BTRFS_I(inode); struct btrfs_root *root = ip->root; struct btrfs_trans_handle *trans; @@ -325,7 +325,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) ip->flags |= BTRFS_INODE_COMPRESS; ip->flags &= ~BTRFS_INODE_NOCOMPRESS; - if (root->fs_info->compress_type == BTRFS_COMPRESS_LZO) + if (fs_info->compress_type == BTRFS_COMPRESS_LZO) comp = "lzo"; else comp = "zlib"; @@ -352,7 +352,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) inode->i_ctime = current_time(inode); ret = btrfs_update_inode(trans, root, inode); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); out_drop: if (ret) { ip->flags = ip_oldflags; @@ -374,7 +374,8 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) { - struct btrfs_fs_info *fs_info = btrfs_sb(file_inode(file)->i_sb); + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_device *device; struct request_queue *q; struct fstrim_range range; @@ -410,7 +411,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) range.len = min(range.len, total_bytes - range.start); range.minlen = max(range.minlen, minlen); - ret = btrfs_trim_fs(fs_info->tree_root, &range); + ret = btrfs_trim_fs(fs_info, &range); if (ret < 0) return ret; @@ -437,6 +438,7 @@ static noinline int create_subvol(struct inode *dir, u64 *async_transid, struct btrfs_qgroup_inherit *inherit) { + struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct btrfs_trans_handle *trans; struct btrfs_key key; struct btrfs_root_item *root_item; @@ -459,7 +461,7 @@ static noinline int create_subvol(struct inode *dir, if (!root_item) return -ENOMEM; - ret = btrfs_find_free_objectid(root->fs_info->tree_root, &objectid); + ret = btrfs_find_free_objectid(fs_info->tree_root, &objectid); if (ret) goto fail_free; @@ -485,14 +487,14 @@ static noinline int create_subvol(struct inode *dir, trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { ret = PTR_ERR(trans); - btrfs_subvolume_release_metadata(root, &block_rsv, + btrfs_subvolume_release_metadata(fs_info, &block_rsv, qgroup_reserved); goto fail_free; } trans->block_rsv = &block_rsv; trans->bytes_reserved = block_rsv.size; - ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid, inherit); + ret = btrfs_qgroup_inherit(trans, fs_info, 0, objectid, inherit); if (ret) goto fail; @@ -502,24 +504,22 @@ static noinline int create_subvol(struct inode *dir, goto fail; } - memset_extent_buffer(leaf, 0, 0, sizeof(struct btrfs_header)); + memzero_extent_buffer(leaf, 0, sizeof(struct btrfs_header)); btrfs_set_header_bytenr(leaf, leaf->start); btrfs_set_header_generation(leaf, trans->transid); btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(leaf, objectid); - write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(), - BTRFS_FSID_SIZE); - write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, - btrfs_header_chunk_tree_uuid(leaf), - BTRFS_UUID_SIZE); + write_extent_buffer_fsid(leaf, fs_info->fsid); + write_extent_buffer_chunk_tree_uuid(leaf, fs_info->chunk_tree_uuid); btrfs_mark_buffer_dirty(leaf); inode_item = &root_item->inode; btrfs_set_stack_inode_generation(inode_item, 1); btrfs_set_stack_inode_size(inode_item, 3); btrfs_set_stack_inode_nlink(inode_item, 1); - btrfs_set_stack_inode_nbytes(inode_item, root->nodesize); + btrfs_set_stack_inode_nbytes(inode_item, + fs_info->nodesize); btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755); btrfs_set_root_flags(root_item, 0); @@ -552,13 +552,13 @@ static noinline int create_subvol(struct inode *dir, key.objectid = objectid; key.offset = 0; key.type = BTRFS_ROOT_ITEM_KEY; - ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, + ret = btrfs_insert_root(trans, fs_info->tree_root, &key, root_item); if (ret) goto fail; key.offset = (u64)-1; - new_root = btrfs_read_fs_root_no_name(root->fs_info, &key); + new_root = btrfs_read_fs_root_no_name(fs_info, &key); if (IS_ERR(new_root)) { ret = PTR_ERR(new_root); btrfs_abort_transaction(trans, ret); @@ -599,14 +599,13 @@ static noinline int create_subvol(struct inode *dir, ret = btrfs_update_inode(trans, root, dir); BUG_ON(ret); - ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, + ret = btrfs_add_root_ref(trans, fs_info, objectid, root->root_key.objectid, btrfs_ino(dir), index, name, namelen); BUG_ON(ret); - ret = btrfs_uuid_tree_add(trans, root->fs_info->uuid_root, - root_item->uuid, BTRFS_UUID_KEY_SUBVOL, - objectid); + ret = btrfs_uuid_tree_add(trans, fs_info, root_item->uuid, + BTRFS_UUID_KEY_SUBVOL, objectid); if (ret) btrfs_abort_transaction(trans, ret); @@ -614,15 +613,15 @@ fail: kfree(root_item); trans->block_rsv = NULL; trans->bytes_reserved = 0; - btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); + btrfs_subvolume_release_metadata(fs_info, &block_rsv, qgroup_reserved); if (async_transid) { *async_transid = trans->transid; - err = btrfs_commit_transaction_async(trans, root, 1); + err = btrfs_commit_transaction_async(trans, 1); if (err) - err = btrfs_commit_transaction(trans, root); + err = btrfs_commit_transaction(trans); } else { - err = btrfs_commit_transaction(trans, root); + err = btrfs_commit_transaction(trans); } if (err && !ret) ret = err; @@ -662,6 +661,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, u64 *async_transid, bool readonly, struct btrfs_qgroup_inherit *inherit) { + struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct inode *inode; struct btrfs_pending_snapshot *pending_snapshot; struct btrfs_trans_handle *trans; @@ -721,19 +721,17 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, goto fail; } - spin_lock(&root->fs_info->trans_lock); + spin_lock(&fs_info->trans_lock); list_add(&pending_snapshot->list, &trans->transaction->pending_snapshots); - spin_unlock(&root->fs_info->trans_lock); + spin_unlock(&fs_info->trans_lock); if (async_transid) { *async_transid = trans->transid; - ret = btrfs_commit_transaction_async(trans, - root->fs_info->extent_root, 1); + ret = btrfs_commit_transaction_async(trans, 1); if (ret) - ret = btrfs_commit_transaction(trans, root); + ret = btrfs_commit_transaction(trans); } else { - ret = btrfs_commit_transaction(trans, - root->fs_info->extent_root); + ret = btrfs_commit_transaction(trans); } if (ret) goto fail; @@ -755,7 +753,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, d_instantiate(dentry, inode); ret = 0; fail: - btrfs_subvolume_release_metadata(BTRFS_I(dir)->root, + btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv, pending_snapshot->qgroup_reserved); dec_and_free: @@ -842,7 +840,8 @@ static noinline int btrfs_mksubvol(struct path *parent, u64 *async_transid, bool readonly, struct btrfs_qgroup_inherit *inherit) { - struct inode *dir = d_inode(parent->dentry); + struct inode *dir = d_inode(parent->dentry); + struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); struct dentry *dentry; int error; @@ -869,7 +868,7 @@ static noinline int btrfs_mksubvol(struct path *parent, if (error) goto out_dput; - down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); + down_read(&fs_info->subvol_sem); if (btrfs_root_refs(&BTRFS_I(dir)->root->root_item) == 0) goto out_up_read; @@ -884,7 +883,7 @@ static noinline int btrfs_mksubvol(struct path *parent, if (!error) fsnotify_mkdir(dir, dentry); out_up_read: - up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); + up_read(&fs_info->subvol_sem); out_dput: dput(dentry); out_unlock: @@ -1268,6 +1267,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, struct btrfs_ioctl_defrag_range_args *range, u64 newer_than, unsigned long max_to_defrag) { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct file_ra_state *ra = NULL; unsigned long last_index; @@ -1365,8 +1365,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (!(inode->i_sb->s_flags & MS_ACTIVE)) break; - if (btrfs_defrag_cancelled(root->fs_info)) { - btrfs_debug(root->fs_info, "defrag_file cancelled"); + if (btrfs_defrag_cancelled(fs_info)) { + btrfs_debug(fs_info, "defrag_file cancelled"); ret = -EAGAIN; break; } @@ -1454,18 +1454,18 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, * we have to make sure the IO is actually started and that * ordered extents get created before we return */ - atomic_inc(&root->fs_info->async_submit_draining); - while (atomic_read(&root->fs_info->nr_async_submits) || - atomic_read(&root->fs_info->async_delalloc_pages)) { - wait_event(root->fs_info->async_submit_wait, - (atomic_read(&root->fs_info->nr_async_submits) == 0 && - atomic_read(&root->fs_info->async_delalloc_pages) == 0)); + atomic_inc(&fs_info->async_submit_draining); + while (atomic_read(&fs_info->nr_async_submits) || + atomic_read(&fs_info->async_delalloc_pages)) { + wait_event(fs_info->async_submit_wait, + (atomic_read(&fs_info->nr_async_submits) == 0 && + atomic_read(&fs_info->async_delalloc_pages) == 0)); } - atomic_dec(&root->fs_info->async_submit_draining); + atomic_dec(&fs_info->async_submit_draining); } if (range->compress_type == BTRFS_COMPRESS_LZO) { - btrfs_set_fs_incompat(root->fs_info, COMPRESS_LZO); + btrfs_set_fs_incompat(fs_info, COMPRESS_LZO); } ret = defrag_count; @@ -1485,10 +1485,12 @@ out_ra: static noinline int btrfs_ioctl_resize(struct file *file, void __user *arg) { + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); u64 new_size; u64 old_size; u64 devid = 1; - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_ioctl_vol_args *vol_args; struct btrfs_trans_handle *trans; struct btrfs_device *device = NULL; @@ -1505,13 +1507,12 @@ static noinline int btrfs_ioctl_resize(struct file *file, if (ret) return ret; - if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, - 1)) { + if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) { mnt_drop_write_file(file); return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; } - mutex_lock(&root->fs_info->volume_mutex); + mutex_lock(&fs_info->volume_mutex); vol_args = memdup_user(arg, sizeof(*vol_args)); if (IS_ERR(vol_args)) { ret = PTR_ERR(vol_args); @@ -1533,19 +1534,19 @@ static noinline int btrfs_ioctl_resize(struct file *file, ret = -EINVAL; goto out_free; } - btrfs_info(root->fs_info, "resizing devid %llu", devid); + btrfs_info(fs_info, "resizing devid %llu", devid); } - device = btrfs_find_device(root->fs_info, devid, NULL, NULL); + device = btrfs_find_device(fs_info, devid, NULL, NULL); if (!device) { - btrfs_info(root->fs_info, "resizer unable to find device %llu", - devid); + btrfs_info(fs_info, "resizer unable to find device %llu", + devid); ret = -ENODEV; goto out_free; } if (!device->writeable) { - btrfs_info(root->fs_info, + btrfs_info(fs_info, "resizer unable to apply on readonly device %llu", devid); ret = -EPERM; @@ -1599,11 +1600,11 @@ static noinline int btrfs_ioctl_resize(struct file *file, goto out_free; } - new_size = div_u64(new_size, root->sectorsize); - new_size *= root->sectorsize; + new_size = div_u64(new_size, fs_info->sectorsize); + new_size *= fs_info->sectorsize; - btrfs_info_in_rcu(root->fs_info, "new size for %s is %llu", - rcu_str_deref(device->name), new_size); + btrfs_info_in_rcu(fs_info, "new size for %s is %llu", + rcu_str_deref(device->name), new_size); if (new_size > old_size) { trans = btrfs_start_transaction(root, 0); @@ -1612,7 +1613,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, goto out_free; } ret = btrfs_grow_device(trans, device, new_size); - btrfs_commit_transaction(trans, root); + btrfs_commit_transaction(trans); } else if (new_size < old_size) { ret = btrfs_shrink_device(device, new_size); } /* equal, nothing need to do */ @@ -1620,8 +1621,8 @@ static noinline int btrfs_ioctl_resize(struct file *file, out_free: kfree(vol_args); out: - mutex_unlock(&root->fs_info->volume_mutex); - atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); + mutex_unlock(&fs_info->volume_mutex); + atomic_set(&fs_info->mutually_exclusive_operation_running, 0); mnt_drop_write_file(file); return ret; } @@ -1774,6 +1775,7 @@ static noinline int btrfs_ioctl_subvol_getflags(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; int ret = 0; u64 flags = 0; @@ -1781,10 +1783,10 @@ static noinline int btrfs_ioctl_subvol_getflags(struct file *file, if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) return -EINVAL; - down_read(&root->fs_info->subvol_sem); + down_read(&fs_info->subvol_sem); if (btrfs_root_readonly(root)) flags |= BTRFS_SUBVOL_RDONLY; - up_read(&root->fs_info->subvol_sem); + up_read(&fs_info->subvol_sem); if (copy_to_user(arg, &flags, sizeof(flags))) ret = -EFAULT; @@ -1796,6 +1798,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; u64 root_flags; @@ -1829,7 +1832,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, goto out_drop_write; } - down_write(&root->fs_info->subvol_sem); + down_write(&fs_info->subvol_sem); /* nothing to do */ if (!!(flags & BTRFS_SUBVOL_RDONLY) == btrfs_root_readonly(root)) @@ -1851,9 +1854,9 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, spin_unlock(&root->root_item_lock); } else { spin_unlock(&root->root_item_lock); - btrfs_warn(root->fs_info, - "Attempt to set subvolume %llu read-write during send", - root->root_key.objectid); + btrfs_warn(fs_info, + "Attempt to set subvolume %llu read-write during send", + root->root_key.objectid); ret = -EPERM; goto out_drop_sem; } @@ -1865,15 +1868,15 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, goto out_reset; } - ret = btrfs_update_root(trans, root->fs_info->tree_root, + ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key, &root->root_item); - btrfs_commit_transaction(trans, root); + btrfs_commit_transaction(trans); out_reset: if (ret) btrfs_set_root_flags(&root->root_item, root_flags); out_drop_sem: - up_write(&root->fs_info->subvol_sem); + up_write(&fs_info->subvol_sem); out_drop_write: mnt_drop_write_file(file); out: @@ -1885,6 +1888,7 @@ out: */ static noinline int may_destroy_subvol(struct btrfs_root *root) { + struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_path *path; struct btrfs_dir_item *di; struct btrfs_key key; @@ -1896,14 +1900,14 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) return -ENOMEM; /* Make sure this root isn't set as the default subvol */ - dir_id = btrfs_super_root_dir(root->fs_info->super_copy); - di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, path, + dir_id = btrfs_super_root_dir(fs_info->super_copy); + di = btrfs_lookup_dir_item(NULL, fs_info->tree_root, path, dir_id, "default", 7, 0); if (di && !IS_ERR(di)) { btrfs_dir_item_key_to_cpu(path->nodes[0], di, &key); if (key.objectid == root->root_key.objectid) { ret = -EPERM; - btrfs_err(root->fs_info, + btrfs_err(fs_info, "deleting default subvolume %llu is not allowed", key.objectid); goto out; @@ -1915,8 +1919,7 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) key.type = BTRFS_ROOT_REF_KEY; key.offset = (u64)-1; - ret = btrfs_search_slot(NULL, root->fs_info->tree_root, - &key, path, 0, 0); + ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0); if (ret < 0) goto out; BUG_ON(ret == 0); @@ -2087,10 +2090,10 @@ static noinline int search_ioctl(struct inode *inode, size_t *buf_size, char __user *ubuf) { + struct btrfs_fs_info *info = btrfs_sb(inode->i_sb); struct btrfs_root *root; struct btrfs_key key; struct btrfs_path *path; - struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; int ret; int num_found = 0; unsigned long sk_offset = 0; @@ -2353,6 +2356,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, void __user *arg) { struct dentry *parent = file->f_path.dentry; + struct btrfs_fs_info *fs_info = btrfs_sb(parent->d_sb); struct dentry *dentry; struct inode *dir = d_inode(parent); struct inode *inode; @@ -2418,7 +2422,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, * rmdir(2). */ err = -EPERM; - if (!btrfs_test_opt(root->fs_info, USER_SUBVOL_RM_ALLOWED)) + if (!btrfs_test_opt(fs_info, USER_SUBVOL_RM_ALLOWED)) goto out_dput; /* @@ -2462,14 +2466,14 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, spin_unlock(&dest->root_item_lock); } else { spin_unlock(&dest->root_item_lock); - btrfs_warn(root->fs_info, - "Attempt to delete subvolume %llu during send", - dest->root_key.objectid); + btrfs_warn(fs_info, + "Attempt to delete subvolume %llu during send", + dest->root_key.objectid); err = -EPERM; goto out_unlock_inode; } - down_write(&root->fs_info->subvol_sem); + down_write(&fs_info->subvol_sem); err = may_destroy_subvol(dest); if (err) @@ -2514,7 +2518,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, if (!test_and_set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &dest->state)) { ret = btrfs_insert_orphan_item(trans, - root->fs_info->tree_root, + fs_info->tree_root, dest->root_key.objectid); if (ret) { btrfs_abort_transaction(trans, ret); @@ -2523,8 +2527,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, } } - ret = btrfs_uuid_tree_rem(trans, root->fs_info->uuid_root, - dest->root_item.uuid, BTRFS_UUID_KEY_SUBVOL, + ret = btrfs_uuid_tree_rem(trans, fs_info, dest->root_item.uuid, + BTRFS_UUID_KEY_SUBVOL, dest->root_key.objectid); if (ret && ret != -ENOENT) { btrfs_abort_transaction(trans, ret); @@ -2532,7 +2536,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, goto out_end_trans; } if (!btrfs_is_empty_uuid(dest->root_item.received_uuid)) { - ret = btrfs_uuid_tree_rem(trans, root->fs_info->uuid_root, + ret = btrfs_uuid_tree_rem(trans, fs_info, dest->root_item.received_uuid, BTRFS_UUID_KEY_RECEIVED_SUBVOL, dest->root_key.objectid); @@ -2546,14 +2550,14 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, out_end_trans: trans->block_rsv = NULL; trans->bytes_reserved = 0; - ret = btrfs_end_transaction(trans, root); + ret = btrfs_end_transaction(trans); if (ret && !err) err = ret; inode->i_flags |= S_DEAD; out_release: - btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); + btrfs_subvolume_release_metadata(fs_info, &block_rsv, qgroup_reserved); out_up_write: - up_write(&root->fs_info->subvol_sem); + up_write(&fs_info->subvol_sem); if (err) { spin_lock(&dest->root_item_lock); root_flags = btrfs_root_flags(&dest->root_item); @@ -2655,7 +2659,7 @@ out: return ret; } -static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) +static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg) { struct btrfs_ioctl_vol_args *vol_args; int ret; @@ -2663,12 +2667,10 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, - 1)) { + if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; - } - mutex_lock(&root->fs_info->volume_mutex); + mutex_lock(&fs_info->volume_mutex); vol_args = memdup_user(arg, sizeof(*vol_args)); if (IS_ERR(vol_args)) { ret = PTR_ERR(vol_args); @@ -2676,21 +2678,22 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) } vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; - ret = btrfs_init_new_device(root, vol_args->name); + ret = btrfs_init_new_device(fs_info, vol_args->name); if (!ret) - btrfs_info(root->fs_info, "disk added %s",vol_args->name); + btrfs_info(fs_info, "disk added %s", vol_args->name); kfree(vol_args); out: - mutex_unlock(&root->fs_info->volume_mutex); - atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); + mutex_unlock(&fs_info->volume_mutex); + atomic_set(&fs_info->mutually_exclusive_operation_running, 0); return ret; } static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_ioctl_vol_args_v2 *vol_args; int ret; @@ -2711,28 +2714,27 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED) return -EOPNOTSUPP; - if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, - 1)) { + if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) { ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; goto out; } - mutex_lock(&root->fs_info->volume_mutex); + mutex_lock(&fs_info->volume_mutex); if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID) { - ret = btrfs_rm_device(root, NULL, vol_args->devid); + ret = btrfs_rm_device(fs_info, NULL, vol_args->devid); } else { vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; - ret = btrfs_rm_device(root, vol_args->name, 0); + ret = btrfs_rm_device(fs_info, vol_args->name, 0); } - mutex_unlock(&root->fs_info->volume_mutex); - atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); + mutex_unlock(&fs_info->volume_mutex); + atomic_set(&fs_info->mutually_exclusive_operation_running, 0); if (!ret) { if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID) - btrfs_info(root->fs_info, "device deleted: id %llu", + btrfs_info(fs_info, "device deleted: id %llu", vol_args->devid); else - btrfs_info(root->fs_info, "device deleted: %s", + btrfs_info(fs_info, "device deleted: %s", vol_args->name); } out: @@ -2744,7 +2746,8 @@ err_drop: static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_ioctl_vol_args *vol_args; int ret; @@ -2755,8 +2758,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) if (ret) return ret; - if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, - 1)) { + if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) { ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; goto out_drop_write; } @@ -2768,26 +2770,27 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) } vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; - mutex_lock(&root->fs_info->volume_mutex); - ret = btrfs_rm_device(root, vol_args->name, 0); - mutex_unlock(&root->fs_info->volume_mutex); + mutex_lock(&fs_info->volume_mutex); + ret = btrfs_rm_device(fs_info, vol_args->name, 0); + mutex_unlock(&fs_info->volume_mutex); if (!ret) - btrfs_info(root->fs_info, "disk deleted %s",vol_args->name); + btrfs_info(fs_info, "disk deleted %s", vol_args->name); kfree(vol_args); out: - atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); + atomic_set(&fs_info->mutually_exclusive_operation_running, 0); out_drop_write: mnt_drop_write_file(file); return ret; } -static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) +static long btrfs_ioctl_fs_info(struct btrfs_fs_info *fs_info, + void __user *arg) { struct btrfs_ioctl_fs_info_args *fi_args; struct btrfs_device *device; - struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; int ret = 0; fi_args = kzalloc(sizeof(*fi_args), GFP_KERNEL); @@ -2796,7 +2799,7 @@ static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) mutex_lock(&fs_devices->device_list_mutex); fi_args->num_devices = fs_devices->num_devices; - memcpy(&fi_args->fsid, root->fs_info->fsid, sizeof(fi_args->fsid)); + memcpy(&fi_args->fsid, fs_info->fsid, sizeof(fi_args->fsid)); list_for_each_entry(device, &fs_devices->devices, dev_list) { if (device->devid > fi_args->max_id) @@ -2804,9 +2807,9 @@ static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) } mutex_unlock(&fs_devices->device_list_mutex); - fi_args->nodesize = root->fs_info->super_copy->nodesize; - fi_args->sectorsize = root->fs_info->super_copy->sectorsize; - fi_args->clone_alignment = root->fs_info->super_copy->sectorsize; + fi_args->nodesize = fs_info->super_copy->nodesize; + fi_args->sectorsize = fs_info->super_copy->sectorsize; + fi_args->clone_alignment = fs_info->super_copy->sectorsize; if (copy_to_user(arg, fi_args, sizeof(*fi_args))) ret = -EFAULT; @@ -2815,11 +2818,12 @@ static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) return ret; } -static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) +static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info, + void __user *arg) { struct btrfs_ioctl_dev_info_args *di_args; struct btrfs_device *dev; - struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; int ret = 0; char *s_uuid = NULL; @@ -2831,7 +2835,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) s_uuid = di_args->uuid; mutex_lock(&fs_devices->device_list_mutex); - dev = btrfs_find_device(root->fs_info, di_args->devid, s_uuid, NULL); + dev = btrfs_find_device(fs_info, di_args->devid, s_uuid, NULL); if (!dev) { ret = -ENODEV; @@ -3305,10 +3309,10 @@ static int clone_finish_inode_update(struct btrfs_trans_handle *trans, ret = btrfs_update_inode(trans, root, inode); if (ret) { btrfs_abort_transaction(trans, ret); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } - ret = btrfs_end_transaction(trans, root); + ret = btrfs_end_transaction(trans); out: return ret; } @@ -3406,9 +3410,10 @@ static int clone_copy_inline_extent(struct inode *src, const u64 size, char *inline_data) { + struct btrfs_fs_info *fs_info = btrfs_sb(dst->i_sb); struct btrfs_root *root = BTRFS_I(dst)->root; const u64 aligned_end = ALIGN(new_key->offset + datal, - root->sectorsize); + fs_info->sectorsize); int ret; struct btrfs_key key; @@ -3529,6 +3534,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, const u64 off, const u64 olen, const u64 olen_aligned, const u64 destoff, int no_time_update) { + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path = NULL; struct extent_buffer *leaf; @@ -3542,9 +3548,9 @@ static int btrfs_clone(struct inode *src, struct inode *inode, u64 last_dest_end = destoff; ret = -ENOMEM; - buf = kmalloc(root->nodesize, GFP_KERNEL | __GFP_NOWARN); + buf = kmalloc(fs_info->nodesize, GFP_KERNEL | __GFP_NOWARN); if (!buf) { - buf = vmalloc(root->nodesize); + buf = vmalloc(fs_info->nodesize); if (!buf) return ret; } @@ -3707,7 +3713,7 @@ process_slot: if (ret != -EOPNOTSUPP) btrfs_abort_transaction(trans, ret); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } @@ -3715,7 +3721,7 @@ process_slot: &new_key, size); if (ret) { btrfs_abort_transaction(trans, ret); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } @@ -3739,7 +3745,8 @@ process_slot: if (disko) { inode_add_bytes(inode, datal); - ret = btrfs_inc_extent_ref(trans, root, + ret = btrfs_inc_extent_ref(trans, + fs_info, disko, diskl, 0, root->root_key.objectid, btrfs_ino(inode), @@ -3747,8 +3754,7 @@ process_slot: if (ret) { btrfs_abort_transaction(trans, ret); - btrfs_end_transaction(trans, - root); + btrfs_end_transaction(trans); goto out; } @@ -3767,7 +3773,7 @@ process_slot: if (comp && (skip || trim)) { ret = -EINVAL; - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } size -= skip + trim; @@ -3783,7 +3789,7 @@ process_slot: if (ret != -EOPNOTSUPP) btrfs_abort_transaction(trans, ret); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } leaf = path->nodes[0]; @@ -3802,7 +3808,7 @@ process_slot: btrfs_release_path(path); last_dest_end = ALIGN(new_key.offset + datal, - root->sectorsize); + fs_info->sectorsize); ret = clone_finish_inode_update(trans, inode, last_dest_end, destoff, olen, @@ -3843,7 +3849,7 @@ process_slot: if (ret) { if (ret != -EOPNOTSUPP) btrfs_abort_transaction(trans, ret); - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } clone_update_extent_map(inode, trans, NULL, last_dest_end, @@ -3863,10 +3869,11 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src, { struct inode *inode = file_inode(file); struct inode *src = file_inode(file_src); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; int ret; u64 len = olen; - u64 bs = root->fs_info->sb->s_blocksize; + u64 bs = fs_info->sb->s_blocksize; int same_inode = src == inode; /* @@ -4007,6 +4014,7 @@ int btrfs_clone_file_range(struct file *src_file, loff_t off, static long btrfs_ioctl_trans_start(struct file *file) { struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; int ret; @@ -4027,7 +4035,7 @@ static long btrfs_ioctl_trans_start(struct file *file) if (ret) goto out; - atomic_inc(&root->fs_info->open_ioctl_trans); + atomic_inc(&fs_info->open_ioctl_trans); ret = -ENOMEM; trans = btrfs_start_ioctl_transaction(root); @@ -4038,7 +4046,7 @@ static long btrfs_ioctl_trans_start(struct file *file) return 0; out_drop: - atomic_dec(&root->fs_info->open_ioctl_trans); + atomic_dec(&fs_info->open_ioctl_trans); mnt_drop_write_file(file); out: return ret; @@ -4047,6 +4055,7 @@ out: static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) { struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *new_root; struct btrfs_dir_item *di; @@ -4077,7 +4086,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) location.type = BTRFS_ROOT_ITEM_KEY; location.offset = (u64)-1; - new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); + new_root = btrfs_read_fs_root_no_name(fs_info, &location); if (IS_ERR(new_root)) { ret = PTR_ERR(new_root); goto out; @@ -4097,13 +4106,13 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) goto out; } - dir_id = btrfs_super_root_dir(root->fs_info->super_copy); - di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, + dir_id = btrfs_super_root_dir(fs_info->super_copy); + di = btrfs_lookup_dir_item(trans, fs_info->tree_root, path, dir_id, "default", 7, 1); if (IS_ERR_OR_NULL(di)) { btrfs_free_path(path); - btrfs_end_transaction(trans, root); - btrfs_err(new_root->fs_info, + btrfs_end_transaction(trans); + btrfs_err(fs_info, "Umm, you don't have the default diritem, this isn't going to work"); ret = -ENOENT; goto out; @@ -4114,8 +4123,8 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_free_path(path); - btrfs_set_fs_incompat(root->fs_info, DEFAULT_SUBVOL); - btrfs_end_transaction(trans, root); + btrfs_set_fs_incompat(fs_info, DEFAULT_SUBVOL); + btrfs_end_transaction(trans); out: mnt_drop_write_file(file); return ret; @@ -4137,7 +4146,8 @@ void btrfs_get_block_group_info(struct list_head *groups_list, } } -static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) +static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info, + void __user *arg) { struct btrfs_ioctl_space_args space_args; struct btrfs_ioctl_space_info space; @@ -4165,7 +4175,7 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) info = NULL; rcu_read_lock(); - list_for_each_entry_rcu(tmp, &root->fs_info->space_info, + list_for_each_entry_rcu(tmp, &fs_info->space_info, list) { if (tmp->flags == types[i]) { info = tmp; @@ -4221,7 +4231,7 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) info = NULL; rcu_read_lock(); - list_for_each_entry_rcu(tmp, &root->fs_info->space_info, + list_for_each_entry_rcu(tmp, &fs_info->space_info, list) { if (tmp->flags == types[i]) { info = tmp; @@ -4252,7 +4262,7 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) * Add global block reserve */ if (slot_count) { - struct btrfs_block_rsv *block_rsv = &root->fs_info->global_block_rsv; + struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; spin_lock(&block_rsv->lock); space.total_bytes = block_rsv->size; @@ -4294,7 +4304,7 @@ long btrfs_ioctl_trans_end(struct file *file) return -EINVAL; file->private_data = NULL; - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); atomic_dec(&root->fs_info->open_ioctl_trans); @@ -4319,9 +4329,9 @@ static noinline long btrfs_ioctl_start_sync(struct btrfs_root *root, goto out; } transid = trans->transid; - ret = btrfs_commit_transaction_async(trans, root, 0); + ret = btrfs_commit_transaction_async(trans, 0); if (ret) { - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); return ret; } out: @@ -4331,7 +4341,7 @@ out: return 0; } -static noinline long btrfs_ioctl_wait_sync(struct btrfs_root *root, +static noinline long btrfs_ioctl_wait_sync(struct btrfs_fs_info *fs_info, void __user *argp) { u64 transid; @@ -4342,12 +4352,12 @@ static noinline long btrfs_ioctl_wait_sync(struct btrfs_root *root, } else { transid = 0; /* current trans */ } - return btrfs_wait_for_commit(root, transid); + return btrfs_wait_for_commit(fs_info, transid); } static long btrfs_ioctl_scrub(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct btrfs_fs_info *fs_info = btrfs_sb(file_inode(file)->i_sb); struct btrfs_ioctl_scrub_args *sa; int ret; @@ -4364,7 +4374,7 @@ static long btrfs_ioctl_scrub(struct file *file, void __user *arg) goto out; } - ret = btrfs_scrub_dev(root->fs_info, sa->devid, sa->start, sa->end, + ret = btrfs_scrub_dev(fs_info, sa->devid, sa->start, sa->end, &sa->progress, sa->flags & BTRFS_SCRUB_READONLY, 0); @@ -4378,15 +4388,15 @@ out: return ret; } -static long btrfs_ioctl_scrub_cancel(struct btrfs_root *root, void __user *arg) +static long btrfs_ioctl_scrub_cancel(struct btrfs_fs_info *fs_info) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; - return btrfs_scrub_cancel(root->fs_info); + return btrfs_scrub_cancel(fs_info); } -static long btrfs_ioctl_scrub_progress(struct btrfs_root *root, +static long btrfs_ioctl_scrub_progress(struct btrfs_fs_info *fs_info, void __user *arg) { struct btrfs_ioctl_scrub_args *sa; @@ -4399,7 +4409,7 @@ static long btrfs_ioctl_scrub_progress(struct btrfs_root *root, if (IS_ERR(sa)) return PTR_ERR(sa); - ret = btrfs_scrub_progress(root, sa->devid, &sa->progress); + ret = btrfs_scrub_progress(fs_info, sa->devid, &sa->progress); if (copy_to_user(arg, sa, sizeof(*sa))) ret = -EFAULT; @@ -4408,7 +4418,7 @@ static long btrfs_ioctl_scrub_progress(struct btrfs_root *root, return ret; } -static long btrfs_ioctl_get_dev_stats(struct btrfs_root *root, +static long btrfs_ioctl_get_dev_stats(struct btrfs_fs_info *fs_info, void __user *arg) { struct btrfs_ioctl_get_dev_stats *sa; @@ -4423,7 +4433,7 @@ static long btrfs_ioctl_get_dev_stats(struct btrfs_root *root, return -EPERM; } - ret = btrfs_get_dev_stats(root, sa); + ret = btrfs_get_dev_stats(fs_info, sa); if (copy_to_user(arg, sa, sizeof(*sa))) ret = -EFAULT; @@ -4432,7 +4442,8 @@ static long btrfs_ioctl_get_dev_stats(struct btrfs_root *root, return ret; } -static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) +static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info, + void __user *arg) { struct btrfs_ioctl_dev_replace_args *p; int ret; @@ -4446,27 +4457,25 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) switch (p->cmd) { case BTRFS_IOCTL_DEV_REPLACE_CMD_START: - if (root->fs_info->sb->s_flags & MS_RDONLY) { + if (fs_info->sb->s_flags & MS_RDONLY) { ret = -EROFS; goto out; } if (atomic_xchg( - &root->fs_info->mutually_exclusive_operation_running, - 1)) { + &fs_info->mutually_exclusive_operation_running, 1)) { ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; } else { - ret = btrfs_dev_replace_by_ioctl(root, p); + ret = btrfs_dev_replace_by_ioctl(fs_info, p); atomic_set( - &root->fs_info->mutually_exclusive_operation_running, - 0); + &fs_info->mutually_exclusive_operation_running, 0); } break; case BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS: - btrfs_dev_replace_status(root->fs_info, p); + btrfs_dev_replace_status(fs_info, p); ret = 0; break; case BTRFS_IOCTL_DEV_REPLACE_CMD_CANCEL: - ret = btrfs_dev_replace_cancel(root->fs_info, p); + ret = btrfs_dev_replace_cancel(fs_info, p); break; default: ret = -EINVAL; @@ -4559,7 +4568,7 @@ static int build_ino_list(u64 inum, u64 offset, u64 root, void *ctx) return 0; } -static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, +static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info, void __user *arg) { int ret = 0; @@ -4572,11 +4581,8 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, return -EPERM; loi = memdup_user(arg, sizeof(*loi)); - if (IS_ERR(loi)) { - ret = PTR_ERR(loi); - loi = NULL; - goto out; - } + if (IS_ERR(loi)) + return PTR_ERR(loi); path = btrfs_alloc_path(); if (!path) { @@ -4592,7 +4598,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, goto out; } - ret = iterate_inodes_from_logical(loi->logical, root->fs_info, path, + ret = iterate_inodes_from_logical(loi->logical, fs_info, path, build_ino_list, inodes); if (ret == -EINVAL) ret = -ENOENT; @@ -4788,25 +4794,24 @@ out: return ret; } -static long btrfs_ioctl_balance_ctl(struct btrfs_root *root, int cmd) +static long btrfs_ioctl_balance_ctl(struct btrfs_fs_info *fs_info, int cmd) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; switch (cmd) { case BTRFS_BALANCE_CTL_PAUSE: - return btrfs_pause_balance(root->fs_info); + return btrfs_pause_balance(fs_info); case BTRFS_BALANCE_CTL_CANCEL: - return btrfs_cancel_balance(root->fs_info); + return btrfs_cancel_balance(fs_info); } return -EINVAL; } -static long btrfs_ioctl_balance_progress(struct btrfs_root *root, +static long btrfs_ioctl_balance_progress(struct btrfs_fs_info *fs_info, void __user *arg) { - struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_ioctl_balance_args *bargs; int ret = 0; @@ -4838,7 +4843,8 @@ out: static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_ioctl_quota_ctl_args *sa; struct btrfs_trans_handle *trans = NULL; int ret; @@ -4857,8 +4863,8 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) goto drop_write; } - down_write(&root->fs_info->subvol_sem); - trans = btrfs_start_transaction(root->fs_info->tree_root, 2); + down_write(&fs_info->subvol_sem); + trans = btrfs_start_transaction(fs_info->tree_root, 2); if (IS_ERR(trans)) { ret = PTR_ERR(trans); goto out; @@ -4866,22 +4872,22 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) switch (sa->cmd) { case BTRFS_QUOTA_CTL_ENABLE: - ret = btrfs_quota_enable(trans, root->fs_info); + ret = btrfs_quota_enable(trans, fs_info); break; case BTRFS_QUOTA_CTL_DISABLE: - ret = btrfs_quota_disable(trans, root->fs_info); + ret = btrfs_quota_disable(trans, fs_info); break; default: ret = -EINVAL; break; } - err = btrfs_commit_transaction(trans, root->fs_info->tree_root); + err = btrfs_commit_transaction(trans); if (err && !ret) ret = err; out: kfree(sa); - up_write(&root->fs_info->subvol_sem); + up_write(&fs_info->subvol_sem); drop_write: mnt_drop_write_file(file); return ret; @@ -4889,7 +4895,9 @@ drop_write: static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_ioctl_qgroup_assign_args *sa; struct btrfs_trans_handle *trans; int ret; @@ -4916,19 +4924,19 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) /* FIXME: check if the IDs really exist */ if (sa->assign) { - ret = btrfs_add_qgroup_relation(trans, root->fs_info, + ret = btrfs_add_qgroup_relation(trans, fs_info, sa->src, sa->dst); } else { - ret = btrfs_del_qgroup_relation(trans, root->fs_info, + ret = btrfs_del_qgroup_relation(trans, fs_info, sa->src, sa->dst); } /* update qgroup status and info */ - err = btrfs_run_qgroups(trans, root->fs_info); + err = btrfs_run_qgroups(trans, fs_info); if (err < 0) - btrfs_handle_fs_error(root->fs_info, err, - "failed to update qgroup status and info"); - err = btrfs_end_transaction(trans, root); + btrfs_handle_fs_error(fs_info, err, + "failed to update qgroup status and info"); + err = btrfs_end_transaction(trans); if (err && !ret) ret = err; @@ -4941,7 +4949,9 @@ drop_write: static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_ioctl_qgroup_create_args *sa; struct btrfs_trans_handle *trans; int ret; @@ -4973,12 +4983,12 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) /* FIXME: check if the IDs really exist */ if (sa->create) { - ret = btrfs_create_qgroup(trans, root->fs_info, sa->qgroupid); + ret = btrfs_create_qgroup(trans, fs_info, sa->qgroupid); } else { - ret = btrfs_remove_qgroup(trans, root->fs_info, sa->qgroupid); + ret = btrfs_remove_qgroup(trans, fs_info, sa->qgroupid); } - err = btrfs_end_transaction(trans, root); + err = btrfs_end_transaction(trans); if (err && !ret) ret = err; @@ -4991,7 +5001,9 @@ drop_write: static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_ioctl_qgroup_limit_args *sa; struct btrfs_trans_handle *trans; int ret; @@ -5024,9 +5036,9 @@ static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) } /* FIXME: check if the IDs really exist */ - ret = btrfs_limit_qgroup(trans, root->fs_info, qgroupid, &sa->lim); + ret = btrfs_limit_qgroup(trans, fs_info, qgroupid, &sa->lim); - err = btrfs_end_transaction(trans, root); + err = btrfs_end_transaction(trans); if (err && !ret) ret = err; @@ -5039,7 +5051,8 @@ drop_write: static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_ioctl_quota_rescan_args *qsa; int ret; @@ -5061,7 +5074,7 @@ static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) goto out; } - ret = btrfs_qgroup_rescan(root->fs_info); + ret = btrfs_qgroup_rescan(fs_info); out: kfree(qsa); @@ -5072,7 +5085,8 @@ drop_write: static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_ioctl_quota_rescan_args *qsa; int ret = 0; @@ -5083,9 +5097,9 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) if (!qsa) return -ENOMEM; - if (root->fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) { + if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN) { qsa->flags = 1; - qsa->progress = root->fs_info->qgroup_rescan_progress.objectid; + qsa->progress = fs_info->qgroup_rescan_progress.objectid; } if (copy_to_user(arg, qsa, sizeof(*qsa))) @@ -5097,18 +5111,20 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); if (!capable(CAP_SYS_ADMIN)) return -EPERM; - return btrfs_qgroup_wait_for_completion(root->fs_info, true); + return btrfs_qgroup_wait_for_completion(fs_info, true); } static long _btrfs_ioctl_set_received_subvol(struct file *file, struct btrfs_ioctl_received_subvol_args *sa) { struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root_item *root_item = &root->root_item; struct btrfs_trans_handle *trans; @@ -5123,7 +5139,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, if (ret < 0) return ret; - down_write(&root->fs_info->subvol_sem); + down_write(&fs_info->subvol_sem); if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { ret = -EINVAL; @@ -5154,8 +5170,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, BTRFS_UUID_SIZE); if (received_uuid_changed && !btrfs_is_empty_uuid(root_item->received_uuid)) - btrfs_uuid_tree_rem(trans, root->fs_info->uuid_root, - root_item->received_uuid, + btrfs_uuid_tree_rem(trans, fs_info, root_item->received_uuid, BTRFS_UUID_KEY_RECEIVED_SUBVOL, root->root_key.objectid); memcpy(root_item->received_uuid, sa->uuid, BTRFS_UUID_SIZE); @@ -5166,15 +5181,14 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, btrfs_set_stack_timespec_sec(&root_item->rtime, sa->rtime.sec); btrfs_set_stack_timespec_nsec(&root_item->rtime, sa->rtime.nsec); - ret = btrfs_update_root(trans, root->fs_info->tree_root, + ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key, &root->root_item); if (ret < 0) { - btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans); goto out; } if (received_uuid_changed && !btrfs_is_empty_uuid(sa->uuid)) { - ret = btrfs_uuid_tree_add(trans, root->fs_info->uuid_root, - sa->uuid, + ret = btrfs_uuid_tree_add(trans, fs_info, sa->uuid, BTRFS_UUID_KEY_RECEIVED_SUBVOL, root->root_key.objectid); if (ret < 0 && ret != -EEXIST) { @@ -5182,14 +5196,14 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, goto out; } } - ret = btrfs_commit_transaction(trans, root); + ret = btrfs_commit_transaction(trans); if (ret < 0) { btrfs_abort_transaction(trans, ret); goto out; } out: - up_write(&root->fs_info->subvol_sem); + up_write(&fs_info->subvol_sem); mnt_drop_write_file(file); return ret; } @@ -5203,11 +5217,8 @@ static long btrfs_ioctl_set_received_subvol_32(struct file *file, int ret = 0; args32 = memdup_user(arg, sizeof(*args32)); - if (IS_ERR(args32)) { - ret = PTR_ERR(args32); - args32 = NULL; - goto out; - } + if (IS_ERR(args32)) + return PTR_ERR(args32); args64 = kmalloc(sizeof(*args64), GFP_KERNEL); if (!args64) { @@ -5255,11 +5266,8 @@ static long btrfs_ioctl_set_received_subvol(struct file *file, int ret = 0; sa = memdup_user(arg, sizeof(*sa)); - if (IS_ERR(sa)) { - ret = PTR_ERR(sa); - sa = NULL; - goto out; - } + if (IS_ERR(sa)) + return PTR_ERR(sa); ret = _btrfs_ioctl_set_received_subvol(file, sa); @@ -5277,20 +5285,22 @@ out: static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); size_t len; int ret; char label[BTRFS_LABEL_SIZE]; - spin_lock(&root->fs_info->super_lock); - memcpy(label, root->fs_info->super_copy->label, BTRFS_LABEL_SIZE); - spin_unlock(&root->fs_info->super_lock); + spin_lock(&fs_info->super_lock); + memcpy(label, fs_info->super_copy->label, BTRFS_LABEL_SIZE); + spin_unlock(&fs_info->super_lock); len = strnlen(label, BTRFS_LABEL_SIZE); if (len == BTRFS_LABEL_SIZE) { - btrfs_warn(root->fs_info, - "label is too long, return the first %zu bytes", --len); + btrfs_warn(fs_info, + "label is too long, return the first %zu bytes", + --len); } ret = copy_to_user(arg, label, len); @@ -5300,8 +5310,10 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; - struct btrfs_super_block *super_block = root->fs_info->super_copy; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_trans_handle *trans; char label[BTRFS_LABEL_SIZE]; int ret; @@ -5313,7 +5325,7 @@ static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) return -EFAULT; if (strnlen(label, BTRFS_LABEL_SIZE) == BTRFS_LABEL_SIZE) { - btrfs_err(root->fs_info, + btrfs_err(fs_info, "unable to set label with more than %d bytes", BTRFS_LABEL_SIZE - 1); return -EINVAL; @@ -5329,10 +5341,10 @@ static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) goto out_unlock; } - spin_lock(&root->fs_info->super_lock); + spin_lock(&fs_info->super_lock); strcpy(super_block->label, label); - spin_unlock(&root->fs_info->super_lock); - ret = btrfs_commit_transaction(trans, root); + spin_unlock(&fs_info->super_lock); + ret = btrfs_commit_transaction(trans); out_unlock: mnt_drop_write_file(file); @@ -5360,8 +5372,9 @@ int btrfs_ioctl_get_supported_features(void __user *arg) static int btrfs_ioctl_get_features(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; - struct btrfs_super_block *super_block = root->fs_info->super_copy; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_ioctl_feature_flags features; features.compat_flags = btrfs_super_compat_flags(super_block); @@ -5374,7 +5387,7 @@ static int btrfs_ioctl_get_features(struct file *file, void __user *arg) return 0; } -static int check_feature_bits(struct btrfs_root *root, +static int check_feature_bits(struct btrfs_fs_info *fs_info, enum btrfs_feature_set set, u64 change_mask, u64 flags, u64 supported_flags, u64 safe_set, u64 safe_clear) @@ -5389,14 +5402,14 @@ static int check_feature_bits(struct btrfs_root *root, if (unsupported) { names = btrfs_printable_features(set, unsupported); if (names) { - btrfs_warn(root->fs_info, - "this kernel does not support the %s feature bit%s", - names, strchr(names, ',') ? "s" : ""); + btrfs_warn(fs_info, + "this kernel does not support the %s feature bit%s", + names, strchr(names, ',') ? "s" : ""); kfree(names); } else - btrfs_warn(root->fs_info, - "this kernel does not support %s bits 0x%llx", - type, unsupported); + btrfs_warn(fs_info, + "this kernel does not support %s bits 0x%llx", + type, unsupported); return -EOPNOTSUPP; } @@ -5404,14 +5417,14 @@ static int check_feature_bits(struct btrfs_root *root, if (disallowed) { names = btrfs_printable_features(set, disallowed); if (names) { - btrfs_warn(root->fs_info, - "can't set the %s feature bit%s while mounted", - names, strchr(names, ',') ? "s" : ""); + btrfs_warn(fs_info, + "can't set the %s feature bit%s while mounted", + names, strchr(names, ',') ? "s" : ""); kfree(names); } else - btrfs_warn(root->fs_info, - "can't set %s bits 0x%llx while mounted", - type, disallowed); + btrfs_warn(fs_info, + "can't set %s bits 0x%llx while mounted", + type, disallowed); return -EPERM; } @@ -5419,30 +5432,32 @@ static int check_feature_bits(struct btrfs_root *root, if (disallowed) { names = btrfs_printable_features(set, disallowed); if (names) { - btrfs_warn(root->fs_info, - "can't clear the %s feature bit%s while mounted", - names, strchr(names, ',') ? "s" : ""); + btrfs_warn(fs_info, + "can't clear the %s feature bit%s while mounted", + names, strchr(names, ',') ? "s" : ""); kfree(names); } else - btrfs_warn(root->fs_info, - "can't clear %s bits 0x%llx while mounted", - type, disallowed); + btrfs_warn(fs_info, + "can't clear %s bits 0x%llx while mounted", + type, disallowed); return -EPERM; } return 0; } -#define check_feature(root, change_mask, flags, mask_base) \ -check_feature_bits(root, FEAT_##mask_base, change_mask, flags, \ +#define check_feature(fs_info, change_mask, flags, mask_base) \ +check_feature_bits(fs_info, FEAT_##mask_base, change_mask, flags, \ BTRFS_FEATURE_ ## mask_base ## _SUPP, \ BTRFS_FEATURE_ ## mask_base ## _SAFE_SET, \ BTRFS_FEATURE_ ## mask_base ## _SAFE_CLEAR) static int btrfs_ioctl_set_features(struct file *file, void __user *arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; - struct btrfs_super_block *super_block = root->fs_info->super_copy; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_ioctl_feature_flags flags[2]; struct btrfs_trans_handle *trans; u64 newflags; @@ -5459,17 +5474,17 @@ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) !flags[0].incompat_flags) return 0; - ret = check_feature(root, flags[0].compat_flags, + ret = check_feature(fs_info, flags[0].compat_flags, flags[1].compat_flags, COMPAT); if (ret) return ret; - ret = check_feature(root, flags[0].compat_ro_flags, + ret = check_feature(fs_info, flags[0].compat_ro_flags, flags[1].compat_ro_flags, COMPAT_RO); if (ret) return ret; - ret = check_feature(root, flags[0].incompat_flags, + ret = check_feature(fs_info, flags[0].incompat_flags, flags[1].incompat_flags, INCOMPAT); if (ret) return ret; @@ -5484,7 +5499,7 @@ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) goto out_drop_write; } - spin_lock(&root->fs_info->super_lock); + spin_lock(&fs_info->super_lock); newflags = btrfs_super_compat_flags(super_block); newflags |= flags[0].compat_flags & flags[1].compat_flags; newflags &= ~(flags[0].compat_flags & ~flags[1].compat_flags); @@ -5499,9 +5514,9 @@ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) newflags |= flags[0].incompat_flags & flags[1].incompat_flags; newflags &= ~(flags[0].incompat_flags & ~flags[1].incompat_flags); btrfs_set_super_incompat_flags(super_block, newflags); - spin_unlock(&root->fs_info->super_lock); + spin_unlock(&fs_info->super_lock); - ret = btrfs_commit_transaction(trans, root); + ret = btrfs_commit_transaction(trans); out_drop_write: mnt_drop_write_file(file); @@ -5511,7 +5526,9 @@ out_drop_write: long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct btrfs_root *root = BTRFS_I(file_inode(file))->root; + struct inode *inode = file_inode(file); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_root *root = BTRFS_I(inode)->root; void __user *argp = (void __user *)arg; switch (cmd) { @@ -5546,15 +5563,15 @@ long btrfs_ioctl(struct file *file, unsigned int case BTRFS_IOC_RESIZE: return btrfs_ioctl_resize(file, argp); case BTRFS_IOC_ADD_DEV: - return btrfs_ioctl_add_dev(root, argp); + return btrfs_ioctl_add_dev(fs_info, argp); case BTRFS_IOC_RM_DEV: return btrfs_ioctl_rm_dev(file, argp); case BTRFS_IOC_RM_DEV_V2: return btrfs_ioctl_rm_dev_v2(file, argp); case BTRFS_IOC_FS_INFO: - return btrfs_ioctl_fs_info(root, argp); + return btrfs_ioctl_fs_info(fs_info, argp); case BTRFS_IOC_DEV_INFO: - return btrfs_ioctl_dev_info(root, argp); + return btrfs_ioctl_dev_info(fs_info, argp); case BTRFS_IOC_BALANCE: return btrfs_ioctl_balance(file, NULL); case BTRFS_IOC_TRANS_START: @@ -5570,40 +5587,40 @@ long btrfs_ioctl(struct file *file, unsigned int case BTRFS_IOC_INO_PATHS: return btrfs_ioctl_ino_to_path(root, argp); case BTRFS_IOC_LOGICAL_INO: - return btrfs_ioctl_logical_to_ino(root, argp); + return btrfs_ioctl_logical_to_ino(fs_info, argp); case BTRFS_IOC_SPACE_INFO: - return btrfs_ioctl_space_info(root, argp); + return btrfs_ioctl_space_info(fs_info, argp); case BTRFS_IOC_SYNC: { int ret; - ret = btrfs_start_delalloc_roots(root->fs_info, 0, -1); + ret = btrfs_start_delalloc_roots(fs_info, 0, -1); if (ret) return ret; - ret = btrfs_sync_fs(file_inode(file)->i_sb, 1); + ret = btrfs_sync_fs(inode->i_sb, 1); /* * The transaction thread may want to do more work, * namely it pokes the cleaner kthread that will start * processing uncleaned subvols. */ - wake_up_process(root->fs_info->transaction_kthread); + wake_up_process(fs_info->transaction_kthread); return ret; } case BTRFS_IOC_START_SYNC: return btrfs_ioctl_start_sync(root, argp); case BTRFS_IOC_WAIT_SYNC: - return btrfs_ioctl_wait_sync(root, argp); + return btrfs_ioctl_wait_sync(fs_info, argp); case BTRFS_IOC_SCRUB: return btrfs_ioctl_scrub(file, argp); case BTRFS_IOC_SCRUB_CANCEL: - return btrfs_ioctl_scrub_cancel(root, argp); + return btrfs_ioctl_scrub_cancel(fs_info); case BTRFS_IOC_SCRUB_PROGRESS: - return btrfs_ioctl_scrub_progress(root, argp); + return btrfs_ioctl_scrub_progress(fs_info, argp); case BTRFS_IOC_BALANCE_V2: return btrfs_ioctl_balance(file, argp); case BTRFS_IOC_BALANCE_CTL: - return btrfs_ioctl_balance_ctl(root, arg); + return btrfs_ioctl_balance_ctl(fs_info, arg); case BTRFS_IOC_BALANCE_PROGRESS: - return btrfs_ioctl_balance_progress(root, argp); + return btrfs_ioctl_balance_progress(fs_info, argp); case BTRFS_IOC_SET_RECEIVED_SUBVOL: return btrfs_ioctl_set_received_subvol(file, argp); #ifdef CONFIG_64BIT @@ -5613,7 +5630,7 @@ long btrfs_ioctl(struct file *file, unsigned int case BTRFS_IOC_SEND: return btrfs_ioctl_send(file, argp); case BTRFS_IOC_GET_DEV_STATS: - return btrfs_ioctl_get_dev_stats(root, argp); + return btrfs_ioctl_get_dev_stats(fs_info, argp); case BTRFS_IOC_QUOTA_CTL: return btrfs_ioctl_quota_ctl(file, argp); case BTRFS_IOC_QGROUP_ASSIGN: @@ -5629,7 +5646,7 @@ long btrfs_ioctl(struct file *file, unsigned int case BTRFS_IOC_QUOTA_RESCAN_WAIT: return btrfs_ioctl_quota_rescan_wait(file, argp); case BTRFS_IOC_DEV_REPLACE: - return btrfs_ioctl_dev_replace(root, argp); + return btrfs_ioctl_dev_replace(fs_info, argp); case BTRFS_IOC_GET_FSLABEL: return btrfs_ioctl_get_fslabel(file, argp); case BTRFS_IOC_SET_FSLABEL: |