| From 5bd2acd99fb3e34c79075cc673f2b47871c541a1 Mon Sep 17 00:00:00 2001 |
| From: Josef Bacik <josef@toxicpanda.com> |
| Date: Wed, 18 Dec 2019 17:20:27 -0500 |
| Subject: [PATCH] btrfs: rework arguments of btrfs_unlink_subvol |
| |
| commit 045d3967b6920b663fc010ad414ade1b24143bd1 upstream. |
| |
| btrfs_unlink_subvol takes the name of the dentry and the root objectid |
| based on what kind of inode this is, either a real subvolume link or a |
| empty one that we inherited as a snapshot. We need to fix how we unlink |
| in the case for BTRFS_EMPTY_SUBVOL_DIR_OBJECTID in the future, so rework |
| btrfs_unlink_subvol to just take the dentry and handle getting the right |
| objectid given the type of inode this is. There is no functional change |
| here, simply pushing the work into btrfs_unlink_subvol() proper. |
| |
| Signed-off-by: Josef Bacik <josef@toxicpanda.com> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
| index 25515b097125..eed3087d5f3e 100644 |
| --- a/fs/btrfs/inode.c |
| +++ b/fs/btrfs/inode.c |
| @@ -4142,18 +4142,30 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) |
| } |
| |
| static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, |
| - struct inode *dir, u64 objectid, |
| - const char *name, int name_len) |
| + struct inode *dir, struct dentry *dentry) |
| { |
| struct btrfs_root *root = BTRFS_I(dir)->root; |
| + struct btrfs_inode *inode = BTRFS_I(d_inode(dentry)); |
| struct btrfs_path *path; |
| struct extent_buffer *leaf; |
| struct btrfs_dir_item *di; |
| struct btrfs_key key; |
| + const char *name = dentry->d_name.name; |
| + int name_len = dentry->d_name.len; |
| u64 index; |
| int ret; |
| + u64 objectid; |
| u64 dir_ino = btrfs_ino(BTRFS_I(dir)); |
| |
| + if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) { |
| + objectid = inode->root->root_key.objectid; |
| + } else if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { |
| + objectid = inode->location.objectid; |
| + } else { |
| + WARN_ON(1); |
| + return -EINVAL; |
| + } |
| + |
| path = btrfs_alloc_path(); |
| if (!path) |
| return -ENOMEM; |
| @@ -4391,8 +4403,7 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry) |
| |
| btrfs_record_snapshot_destroy(trans, BTRFS_I(dir)); |
| |
| - ret = btrfs_unlink_subvol(trans, dir, dest->root_key.objectid, |
| - dentry->d_name.name, dentry->d_name.len); |
| + ret = btrfs_unlink_subvol(trans, dir, dentry); |
| if (ret) { |
| err = ret; |
| btrfs_abort_transaction(trans, ret); |
| @@ -4487,10 +4498,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) |
| return PTR_ERR(trans); |
| |
| if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { |
| - err = btrfs_unlink_subvol(trans, dir, |
| - BTRFS_I(inode)->location.objectid, |
| - dentry->d_name.name, |
| - dentry->d_name.len); |
| + err = btrfs_unlink_subvol(trans, dir, dentry); |
| goto out; |
| } |
| |
| @@ -9479,7 +9487,6 @@ static int btrfs_rename_exchange(struct inode *old_dir, |
| u64 new_ino = btrfs_ino(BTRFS_I(new_inode)); |
| u64 old_idx = 0; |
| u64 new_idx = 0; |
| - u64 root_objectid; |
| int ret; |
| bool root_log_pinned = false; |
| bool dest_log_pinned = false; |
| @@ -9585,10 +9592,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, |
| |
| /* src is a subvolume */ |
| if (old_ino == BTRFS_FIRST_FREE_OBJECTID) { |
| - root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; |
| - ret = btrfs_unlink_subvol(trans, old_dir, root_objectid, |
| - old_dentry->d_name.name, |
| - old_dentry->d_name.len); |
| + ret = btrfs_unlink_subvol(trans, old_dir, old_dentry); |
| } else { /* src is an inode */ |
| ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir), |
| BTRFS_I(old_dentry->d_inode), |
| @@ -9604,10 +9608,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, |
| |
| /* dest is a subvolume */ |
| if (new_ino == BTRFS_FIRST_FREE_OBJECTID) { |
| - root_objectid = BTRFS_I(new_inode)->root->root_key.objectid; |
| - ret = btrfs_unlink_subvol(trans, new_dir, root_objectid, |
| - new_dentry->d_name.name, |
| - new_dentry->d_name.len); |
| + ret = btrfs_unlink_subvol(trans, new_dir, new_dentry); |
| } else { /* dest is an inode */ |
| ret = __btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir), |
| BTRFS_I(new_dentry->d_inode), |
| @@ -9805,7 +9806,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
| struct inode *new_inode = d_inode(new_dentry); |
| struct inode *old_inode = d_inode(old_dentry); |
| u64 index = 0; |
| - u64 root_objectid; |
| int ret; |
| u64 old_ino = btrfs_ino(BTRFS_I(old_inode)); |
| bool log_pinned = false; |
| @@ -9913,10 +9913,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
| BTRFS_I(old_inode), 1); |
| |
| if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) { |
| - root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; |
| - ret = btrfs_unlink_subvol(trans, old_dir, root_objectid, |
| - old_dentry->d_name.name, |
| - old_dentry->d_name.len); |
| + ret = btrfs_unlink_subvol(trans, old_dir, old_dentry); |
| } else { |
| ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir), |
| BTRFS_I(d_inode(old_dentry)), |
| @@ -9935,10 +9932,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
| new_inode->i_ctime = current_time(new_inode); |
| if (unlikely(btrfs_ino(BTRFS_I(new_inode)) == |
| BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { |
| - root_objectid = BTRFS_I(new_inode)->location.objectid; |
| - ret = btrfs_unlink_subvol(trans, new_dir, root_objectid, |
| - new_dentry->d_name.name, |
| - new_dentry->d_name.len); |
| + ret = btrfs_unlink_subvol(trans, new_dir, new_dentry); |
| BUG_ON(new_inode->i_nlink == 0); |
| } else { |
| ret = btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir), |
| -- |
| 2.7.4 |
| |