aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 18abea802794..2b15daa3a9f2 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -236,6 +236,7 @@ static int wait_for_commit(struct btrfs_root *root,
236struct dirty_root { 236struct dirty_root {
237 struct list_head list; 237 struct list_head list;
238 struct btrfs_root *root; 238 struct btrfs_root *root;
239 struct btrfs_root *latest_root;
239}; 240};
240 241
241int btrfs_add_dead_root(struct btrfs_root *root, struct list_head *dead_list) 242int btrfs_add_dead_root(struct btrfs_root *root, struct list_head *dead_list)
@@ -278,6 +279,15 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
278 btrfs_root_blocknr(&root->root_item)); 279 btrfs_root_blocknr(&root->root_item));
279 brelse(root->commit_root); 280 brelse(root->commit_root);
280 root->commit_root = NULL; 281 root->commit_root = NULL;
282
283 /* make sure to update the root on disk
284 * so we get any updates to the block used
285 * counts
286 */
287 err = btrfs_update_root(trans,
288 root->fs_info->tree_root,
289 &root->root_key,
290 &root->root_item);
281 continue; 291 continue;
282 } 292 }
283 dirty = kmalloc(sizeof(*dirty), GFP_NOFS); 293 dirty = kmalloc(sizeof(*dirty), GFP_NOFS);
@@ -291,6 +301,7 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
291 301
292 memcpy(dirty->root, root, sizeof(*root)); 302 memcpy(dirty->root, root, sizeof(*root));
293 dirty->root->node = root->commit_root; 303 dirty->root->node = root->commit_root;
304 dirty->latest_root = root;
294 root->commit_root = NULL; 305 root->commit_root = NULL;
295 306
296 root->root_key.offset = root->fs_info->generation; 307 root->root_key.offset = root->fs_info->generation;
@@ -384,20 +395,29 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
384{ 395{
385 struct dirty_root *dirty; 396 struct dirty_root *dirty;
386 struct btrfs_trans_handle *trans; 397 struct btrfs_trans_handle *trans;
398 u64 num_blocks;
399 u64 blocks_used;
387 int ret = 0; 400 int ret = 0;
388 int err; 401 int err;
389 402
390 while(!list_empty(list)) { 403 while(!list_empty(list)) {
404 struct btrfs_root *root;
405
391 mutex_lock(&tree_root->fs_info->fs_mutex); 406 mutex_lock(&tree_root->fs_info->fs_mutex);
392 dirty = list_entry(list->next, struct dirty_root, list); 407 dirty = list_entry(list->next, struct dirty_root, list);
393 list_del_init(&dirty->list); 408 list_del_init(&dirty->list);
394 409
410 num_blocks = btrfs_root_blocks_used(&dirty->root->root_item);
411 root = dirty->latest_root;
412
395 while(1) { 413 while(1) {
396 trans = btrfs_start_transaction(tree_root, 1); 414 trans = btrfs_start_transaction(tree_root, 1);
415
397 ret = btrfs_drop_snapshot(trans, dirty->root); 416 ret = btrfs_drop_snapshot(trans, dirty->root);
398 if (ret != -EAGAIN) { 417 if (ret != -EAGAIN) {
399 break; 418 break;
400 } 419 }
420
401 err = btrfs_update_root(trans, 421 err = btrfs_update_root(trans,
402 tree_root, 422 tree_root,
403 &dirty->root->root_key, 423 &dirty->root->root_key,
@@ -414,9 +434,19 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
414 mutex_lock(&tree_root->fs_info->fs_mutex); 434 mutex_lock(&tree_root->fs_info->fs_mutex);
415 } 435 }
416 BUG_ON(ret); 436 BUG_ON(ret);
437
438 num_blocks -= btrfs_root_blocks_used(&dirty->root->root_item);
439 blocks_used = btrfs_root_blocks_used(&root->root_item);
440 if (num_blocks) {
441 record_root_in_trans(root);
442 btrfs_set_root_blocks_used(&root->root_item,
443 blocks_used - num_blocks);
444 }
417 ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key); 445 ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
418 if (ret) 446 if (ret) {
447 BUG();
419 break; 448 break;
449 }
420 ret = btrfs_end_transaction(trans, tree_root); 450 ret = btrfs_end_transaction(trans, tree_root);
421 BUG_ON(ret); 451 BUG_ON(ret);
422 452
@@ -534,10 +564,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
534 wake_up(&cur_trans->commit_wait); 564 wake_up(&cur_trans->commit_wait);
535 put_transaction(cur_trans); 565 put_transaction(cur_trans);
536 put_transaction(cur_trans); 566 put_transaction(cur_trans);
567
537 if (root->fs_info->closing) 568 if (root->fs_info->closing)
538 list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots); 569 list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots);
539 else 570 else
540 list_splice_init(&dirty_fs_roots, &root->fs_info->dead_roots); 571 list_splice_init(&dirty_fs_roots, &root->fs_info->dead_roots);
572
541 mutex_unlock(&root->fs_info->trans_mutex); 573 mutex_unlock(&root->fs_info->trans_mutex);
542 kmem_cache_free(btrfs_trans_handle_cachep, trans); 574 kmem_cache_free(btrfs_trans_handle_cachep, trans);
543 575