]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Mon, 20 Jan 2020 03:18:35 +0000 (22:18 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 20 Jan 2020 03:21:26 +0000 (22:21 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/btrfs-rework-arguments-of-btrfs_unlink_subvol.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/btrfs-rework-arguments-of-btrfs_unlink_subvol.patch b/queue-5.4/btrfs-rework-arguments-of-btrfs_unlink_subvol.patch
new file mode 100644 (file)
index 0000000..b752268
--- /dev/null
@@ -0,0 +1,151 @@
+From 3cf4bda4673838c6267b85f71721f4c91b30d1c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Dec 2019 17:20:27 -0500
+Subject: btrfs: rework arguments of btrfs_unlink_subvol
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 045d3967b6920b663fc010ad414ade1b24143bd1 ]
+
+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: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 46 ++++++++++++++++++++--------------------------
+ 1 file changed, 20 insertions(+), 26 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 9e2a9b5449d9..6f0568fb5899 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4215,18 +4215,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;
+@@ -4475,8 +4487,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);
+@@ -4571,10 +4582,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;
+       }
+@@ -9530,7 +9538,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;
+@@ -9636,10 +9643,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),
+@@ -9655,10 +9659,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),
+@@ -9856,7 +9857,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;
+@@ -9964,10 +9964,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)),
+@@ -9986,10 +9983,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.20.1
+
index 182ce90da10da9601bce6d4a043e15ae04246791..8edfd45ea00675db8f8ae297e75984a7e516bfe1 100644 (file)
@@ -80,6 +80,7 @@ mm-huge_memory.c-thp-fix-conflict-of-above-47bit-hint-address-and-pmd-alignment.
 mm-memcg-slab-fix-percpu-slab-vmstats-flushing.patch
 mm-memcg-slab-call-flush_memcg_workqueue-only-if-memcg-workqueue-is-valid.patch
 mm-debug_pagealloc-don-t-rely-on-static-keys-too-early.patch
+btrfs-rework-arguments-of-btrfs_unlink_subvol.patch
 btrfs-fix-invalid-removal-of-root-ref.patch
 btrfs-do-not-delete-mismatched-root-refs.patch
 btrfs-relocation-fix-reloc_root-lifespan-and-access.patch