diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c571734d5e5a..b83ed5e64a32 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -487,19 +487,40 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
487 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, | 487 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, |
488 | struct btrfs_root *root) | 488 | struct btrfs_root *root) |
489 | { | 489 | { |
490 | return __btrfs_end_transaction(trans, root, 0, 1); | 490 | int ret; |
491 | |||
492 | ret = __btrfs_end_transaction(trans, root, 0, 1); | ||
493 | if (ret) | ||
494 | return ret; | ||
495 | return 0; | ||
491 | } | 496 | } |
492 | 497 | ||
493 | int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, | 498 | int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, |
494 | struct btrfs_root *root) | 499 | struct btrfs_root *root) |
495 | { | 500 | { |
496 | return __btrfs_end_transaction(trans, root, 1, 1); | 501 | int ret; |
502 | |||
503 | ret = __btrfs_end_transaction(trans, root, 1, 1); | ||
504 | if (ret) | ||
505 | return ret; | ||
506 | return 0; | ||
497 | } | 507 | } |
498 | 508 | ||
499 | int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans, | 509 | int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans, |
500 | struct btrfs_root *root) | 510 | struct btrfs_root *root) |
501 | { | 511 | { |
502 | return __btrfs_end_transaction(trans, root, 0, 0); | 512 | int ret; |
513 | |||
514 | ret = __btrfs_end_transaction(trans, root, 0, 0); | ||
515 | if (ret) | ||
516 | return ret; | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans, | ||
521 | struct btrfs_root *root) | ||
522 | { | ||
523 | return __btrfs_end_transaction(trans, root, 1, 1); | ||
503 | } | 524 | } |
504 | 525 | ||
505 | /* | 526 | /* |
@@ -967,7 +988,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
967 | BUG_ON(ret); | 988 | BUG_ON(ret); |
968 | ret = btrfs_insert_dir_item(trans, parent_root, | 989 | ret = btrfs_insert_dir_item(trans, parent_root, |
969 | dentry->d_name.name, dentry->d_name.len, | 990 | dentry->d_name.name, dentry->d_name.len, |
970 | parent_inode->i_ino, &key, | 991 | parent_inode, &key, |
971 | BTRFS_FT_DIR, index); | 992 | BTRFS_FT_DIR, index); |
972 | BUG_ON(ret); | 993 | BUG_ON(ret); |
973 | 994 | ||
@@ -1037,6 +1058,14 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
1037 | int ret; | 1058 | int ret; |
1038 | 1059 | ||
1039 | list_for_each_entry(pending, head, list) { | 1060 | list_for_each_entry(pending, head, list) { |
1061 | /* | ||
1062 | * We must deal with the delayed items before creating | ||
1063 | * snapshots, or we will create a snapthot with inconsistent | ||
1064 | * information. | ||
1065 | */ | ||
1066 | ret = btrfs_run_delayed_items(trans, fs_info->fs_root); | ||
1067 | BUG_ON(ret); | ||
1068 | |||
1040 | ret = create_pending_snapshot(trans, fs_info, pending); | 1069 | ret = create_pending_snapshot(trans, fs_info, pending); |
1041 | BUG_ON(ret); | 1070 | BUG_ON(ret); |
1042 | } | 1071 | } |
@@ -1290,6 +1319,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1290 | BUG_ON(ret); | 1319 | BUG_ON(ret); |
1291 | } | 1320 | } |
1292 | 1321 | ||
1322 | ret = btrfs_run_delayed_items(trans, root); | ||
1323 | BUG_ON(ret); | ||
1324 | |||
1293 | /* | 1325 | /* |
1294 | * rename don't use btrfs_join_transaction, so, once we | 1326 | * rename don't use btrfs_join_transaction, so, once we |
1295 | * set the transaction to blocked above, we aren't going | 1327 | * set the transaction to blocked above, we aren't going |
@@ -1316,6 +1348,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1316 | ret = create_pending_snapshots(trans, root->fs_info); | 1348 | ret = create_pending_snapshots(trans, root->fs_info); |
1317 | BUG_ON(ret); | 1349 | BUG_ON(ret); |
1318 | 1350 | ||
1351 | ret = btrfs_run_delayed_items(trans, root); | ||
1352 | BUG_ON(ret); | ||
1353 | |||
1319 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 1354 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
1320 | BUG_ON(ret); | 1355 | BUG_ON(ret); |
1321 | 1356 | ||
@@ -1432,6 +1467,8 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1432 | root = list_entry(list.next, struct btrfs_root, root_list); | 1467 | root = list_entry(list.next, struct btrfs_root, root_list); |
1433 | list_del(&root->root_list); | 1468 | list_del(&root->root_list); |
1434 | 1469 | ||
1470 | btrfs_kill_all_delayed_nodes(root); | ||
1471 | |||
1435 | if (btrfs_header_backref_rev(root->node) < | 1472 | if (btrfs_header_backref_rev(root->node) < |
1436 | BTRFS_MIXED_BACKREF_REV) | 1473 | BTRFS_MIXED_BACKREF_REV) |
1437 | btrfs_drop_snapshot(root, NULL, 0); | 1474 | btrfs_drop_snapshot(root, NULL, 0); |