btrfs: perform data management operations outside of inode lock
authorNikolay Borisov <nborisov@suse.com>
Wed, 17 Jun 2020 09:10:43 +0000 (12:10 +0300)
committerDavid Sterba <dsterba@suse.com>
Mon, 27 Jul 2020 10:55:27 +0000 (12:55 +0200)
btrfs_alloc_data_chunk_ondemand and btrfs_free_reserved_data_space_noquota
don't really use the guts of the inodes being passed to them. This
implies it's not required to call them under extent lock. Move code
around in prealloc_file_extent_cluster to do the heavy, data alloc/free
operations outside of the lock. This also makes the 'out' label
unnecessary, so remove it.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/relocation.c

index ade45fb..f7feada 100644 (file)
@@ -2584,17 +2584,15 @@ int prealloc_file_extent_cluster(struct inode *inode,
        int ret = 0;
        u64 prealloc_start = cluster->start - offset;
        u64 prealloc_end = cluster->end - offset;
-       u64 cur_offset;
+       u64 cur_offset = prealloc_start;
 
        BUG_ON(cluster->start != cluster->boundary[0]);
-       inode_lock(inode);
-
        ret = btrfs_alloc_data_chunk_ondemand(BTRFS_I(inode),
                                              prealloc_end + 1 - prealloc_start);
        if (ret)
-               goto out;
+               return ret;
 
-       cur_offset = prealloc_start;
+       inode_lock(inode);
        while (nr < cluster->nr) {
                start = cluster->boundary[nr] - offset;
                if (nr + 1 < cluster->nr)
@@ -2613,11 +2611,11 @@ int prealloc_file_extent_cluster(struct inode *inode,
                        break;
                nr++;
        }
+       inode_unlock(inode);
+
        if (cur_offset < prealloc_end)
                btrfs_free_reserved_data_space_noquota(inode,
                                               prealloc_end + 1 - cur_offset);
-out:
-       inode_unlock(inode);
        return ret;
 }