aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2015-04-24 14:00:00 -0400
committerChris Mason <clm@fb.com>2015-04-24 14:52:25 -0400
commita3bdccc4e683f0ac69230707ed3fa20e7cf73a79 (patch)
tree7cec1e92ccfa9fc236190810acb55f025e480d9d
parent85db36cfb3de1422aeafb4e2ce83396333b744bb (diff)
Btrfs: prevent list corruption during free space cache processing
__btrfs_write_out_cache is holding the ctl->tree_lock while it prepares a list of bitmaps to record in the free space cache. It was dropping the lock while it worked on other components, which made a window for free_bitmap() to free the bitmap struct without removing it from the list. This changes things to hold the lock the whole time, and also makes sure we hold the lock during enospc cleanup. Reported-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/free-space-cache.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index d773f229d14d..81fa75a8e1f3 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -1119,10 +1119,7 @@ static int flush_dirty_cache(struct inode *inode)
1119} 1119}
1120 1120
1121static void noinline_for_stack 1121static void noinline_for_stack
1122cleanup_write_cache_enospc(struct inode *inode, 1122cleanup_bitmap_list(struct list_head *bitmap_list)
1123 struct btrfs_io_ctl *io_ctl,
1124 struct extent_state **cached_state,
1125 struct list_head *bitmap_list)
1126{ 1123{
1127 struct list_head *pos, *n; 1124 struct list_head *pos, *n;
1128 1125
@@ -1131,6 +1128,14 @@ cleanup_write_cache_enospc(struct inode *inode,
1131 list_entry(pos, struct btrfs_free_space, list); 1128 list_entry(pos, struct btrfs_free_space, list);
1132 list_del_init(&entry->list); 1129 list_del_init(&entry->list);
1133 } 1130 }
1131}
1132
1133static void noinline_for_stack
1134cleanup_write_cache_enospc(struct inode *inode,
1135 struct btrfs_io_ctl *io_ctl,
1136 struct extent_state **cached_state,
1137 struct list_head *bitmap_list)
1138{
1134 io_ctl_drop_pages(io_ctl); 1139 io_ctl_drop_pages(io_ctl);
1135 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, 1140 unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
1136 i_size_read(inode) - 1, cached_state, 1141 i_size_read(inode) - 1, cached_state,
@@ -1266,11 +1271,8 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
1266 ret = write_cache_extent_entries(io_ctl, ctl, 1271 ret = write_cache_extent_entries(io_ctl, ctl,
1267 block_group, &entries, &bitmaps, 1272 block_group, &entries, &bitmaps,
1268 &bitmap_list); 1273 &bitmap_list);
1269 spin_unlock(&ctl->tree_lock); 1274 if (ret)
1270 if (ret) { 1275 goto out_nospc_locked;
1271 mutex_unlock(&ctl->cache_writeout_mutex);
1272 goto out_nospc;
1273 }
1274 1276
1275 /* 1277 /*
1276 * Some spaces that are freed in the current transaction are pinned, 1278 * Some spaces that are freed in the current transaction are pinned,
@@ -1281,17 +1283,14 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
1281 * the dirty list and redo it. No locking needed 1283 * the dirty list and redo it. No locking needed
1282 */ 1284 */
1283 ret = write_pinned_extent_entries(root, block_group, io_ctl, &entries); 1285 ret = write_pinned_extent_entries(root, block_group, io_ctl, &entries);
1284 if (ret) { 1286 if (ret)
1285 mutex_unlock(&ctl->cache_writeout_mutex); 1287 goto out_nospc_locked;
1286 goto out_nospc;
1287 }
1288 1288
1289 /* 1289 /*
1290 * At last, we write out all the bitmaps and keep cache_writeout_mutex 1290 * At last, we write out all the bitmaps and keep cache_writeout_mutex
1291 * locked while doing it because a concurrent trim can be manipulating 1291 * locked while doing it because a concurrent trim can be manipulating
1292 * or freeing the bitmap. 1292 * or freeing the bitmap.
1293 */ 1293 */
1294 spin_lock(&ctl->tree_lock);
1295 ret = write_bitmap_entries(io_ctl, &bitmap_list); 1294 ret = write_bitmap_entries(io_ctl, &bitmap_list);
1296 spin_unlock(&ctl->tree_lock); 1295 spin_unlock(&ctl->tree_lock);
1297 mutex_unlock(&ctl->cache_writeout_mutex); 1296 mutex_unlock(&ctl->cache_writeout_mutex);
@@ -1344,6 +1343,11 @@ out:
1344 iput(inode); 1343 iput(inode);
1345 return ret; 1344 return ret;
1346 1345
1346out_nospc_locked:
1347 cleanup_bitmap_list(&bitmap_list);
1348 spin_unlock(&ctl->tree_lock);
1349 mutex_unlock(&ctl->cache_writeout_mutex);
1350
1347out_nospc: 1351out_nospc:
1348 cleanup_write_cache_enospc(inode, io_ctl, &cached_state, &bitmap_list); 1352 cleanup_write_cache_enospc(inode, io_ctl, &cached_state, &bitmap_list);
1349 1353