Răsfoiți Sursa

btrfs: fix deadlock when writing out space cache

If we fail to prepare our pages for whatever reason (out of memory in
our case) we need to make sure to drop the block_group->data_rwsem,
otherwise hilarity ensues.

Signed-off-by: Josef Bacik <jbacik@fb.com>
Reviewed-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ add label and use existing unlocking code ]
Signed-off-by: David Sterba <dsterba@suse.com>
Josef Bacik 7 ani în urmă
părinte
comite
b77000ed55
1 a modificat fișierele cu 2 adăugiri și 1 ștergeri
  1. 2 1
      fs/btrfs/free-space-cache.c

+ 2 - 1
fs/btrfs/free-space-cache.c

@@ -1264,7 +1264,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
 	/* Lock all pages first so we can lock the extent safely. */
 	/* Lock all pages first so we can lock the extent safely. */
 	ret = io_ctl_prepare_pages(io_ctl, inode, 0);
 	ret = io_ctl_prepare_pages(io_ctl, inode, 0);
 	if (ret)
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 
 	lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
 	lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
 			 &cached_state);
 			 &cached_state);
@@ -1358,6 +1358,7 @@ out_nospc_locked:
 out_nospc:
 out_nospc:
 	cleanup_write_cache_enospc(inode, io_ctl, &cached_state);
 	cleanup_write_cache_enospc(inode, io_ctl, &cached_state);
 
 
+out_unlock:
 	if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA))
 	if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA))
 		up_write(&block_group->data_rwsem);
 		up_write(&block_group->data_rwsem);