]> git.hungrycats.org Git - linux/commitdiff
Btrfs: fix number of transaction units for renames with whiteout
authorFilipe Manana <fdmanana@suse.com>
Thu, 5 May 2016 09:26:26 +0000 (10:26 +0100)
committerZygo Blaxell <zblaxell@waya.furryterror.org>
Wed, 17 Aug 2016 02:40:49 +0000 (22:40 -0400)
When we do a rename with the whiteout flag, we need to create the whiteout
inode, which in the worst case requires 5 transaction units (1 inode item,
1 inode ref, 2 dir items and 1 xattr if selinux is enabled). So bump the
number of transaction units from 11 to 16 if the whiteout flag is set.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
(cherry picked from commit 5062af35c3c6e49110ab1ec99295339259298a3d)

fs/btrfs/inode.c

index 9c18a509f8de551a820cc0aeede88e8c358e67f4..7ac22f8f724a251c9fdb4073271368cff6521a34 100644 (file)
@@ -9483,6 +9483,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                           struct inode *new_dir, struct dentry *new_dentry)
 {
        struct btrfs_trans_handle *trans;
+       unsigned int trans_num_items;
        struct btrfs_root *root = BTRFS_I(old_dir)->root;
        struct btrfs_root *dest = BTRFS_I(new_dir)->root;
        struct inode *new_inode = d_inode(new_dentry);
@@ -9544,8 +9545,14 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
         * would require 5 item modifications, so we'll assume their normal
         * inodes.  So 5 * 2 is 10, plus 1 for the new link, so 11 total items
         * should cover the worst case number of items we'll modify.
+        * If our rename has the whiteout flag, we need more 5 units for the
+        * new inode (1 inode item, 1 inode ref, 2 dir items and 1 xattr item
+        * when selinux is enabled).
         */
-       trans = btrfs_start_transaction(root, 11);
+       trans_num_items = 11;
+       if (flags & RENAME_WHITEOUT)
+               trans_num_items += 5;
+       trans = btrfs_start_transaction(root, trans_num_items);
        if (IS_ERR(trans)) {
                 ret = PTR_ERR(trans);
                 goto out_notrans;