Btrfs: don't take inode delalloc mutex if we're a free space inode
authorJosef Bacik <jbacik@fusionio.com>
Fri, 14 Dec 2012 18:48:14 +0000 (13:48 -0500)
committerChris Mason <chris.mason@fusionio.com>
Mon, 17 Dec 2012 01:46:29 +0000 (20:46 -0500)
This confuses and angers lockdep even though it's ok.  We don't really need
the lock for free space inodes since only the transaction committer will be
reserving space.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/extent-tree.c

index afc3ac5e57d7b0d96f2a0bf30d705b21676b0856..d133edfcd449988f14f140f0115ab5069ae023b9 100644 (file)
@@ -4535,16 +4535,25 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        int extra_reserve = 0;
        enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL;
        int ret;
+       bool delalloc_lock = true;
 
-       /* Need to be holding the i_mutex here if we aren't free space cache */
-       if (btrfs_is_free_space_inode(inode))
+       /* If we are a free space inode we need to not flush since we will be in
+        * the middle of a transaction commit.  We also don't need the delalloc
+        * mutex since we won't race with anybody.  We need this mostly to make
+        * lockdep shut its filthy mouth.
+        */
+       if (btrfs_is_free_space_inode(inode)) {
                flush = BTRFS_RESERVE_NO_FLUSH;
+               delalloc_lock = false;
+       }
 
        if (flush != BTRFS_RESERVE_NO_FLUSH &&
            btrfs_transaction_in_commit(root->fs_info))
                schedule_timeout(1);
 
-       mutex_lock(&BTRFS_I(inode)->delalloc_mutex);
+       if (delalloc_lock)
+               mutex_lock(&BTRFS_I(inode)->delalloc_mutex);
+
        num_bytes = ALIGN(num_bytes, root->sectorsize);
 
        spin_lock(&BTRFS_I(inode)->lock);
@@ -4577,7 +4586,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
                        spin_lock(&BTRFS_I(inode)->lock);
                        calc_csum_metadata_size(inode, num_bytes, 0);
                        spin_unlock(&BTRFS_I(inode)->lock);
-                       mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
+                       if (delalloc_lock)
+                               mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
                        return ret;
                }
        }
@@ -4616,7 +4626,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
                        btrfs_qgroup_free(root, num_bytes +
                                                nr_extents * root->leafsize);
                }
-               mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
+               if (delalloc_lock)
+                       mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
                return ret;
        }
 
@@ -4628,7 +4639,9 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        }
        BTRFS_I(inode)->reserved_extents += nr_extents;
        spin_unlock(&BTRFS_I(inode)->lock);
-       mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
+
+       if (delalloc_lock)
+               mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
 
        if (to_reserve)
                trace_btrfs_space_reservation(root->fs_info,"delalloc",