aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-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