diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 8 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 21 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 1 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 1 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 13 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 2 |
6 files changed, 39 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index fdba4f1b634e..0621ab90b1a5 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -297,6 +297,7 @@ struct btrfs_super_block { | |||
297 | __le32 leafsize; | 297 | __le32 leafsize; |
298 | __le32 stripesize; | 298 | __le32 stripesize; |
299 | __le32 sys_chunk_array_size; | 299 | __le32 sys_chunk_array_size; |
300 | __le64 chunk_root_generation; | ||
300 | u8 root_level; | 301 | u8 root_level; |
301 | u8 chunk_root_level; | 302 | u8 chunk_root_level; |
302 | u8 log_root_level; | 303 | u8 log_root_level; |
@@ -448,6 +449,7 @@ struct btrfs_dir_item { | |||
448 | 449 | ||
449 | struct btrfs_root_item { | 450 | struct btrfs_root_item { |
450 | struct btrfs_inode_item inode; | 451 | struct btrfs_inode_item inode; |
452 | __le64 generation; | ||
451 | __le64 root_dirid; | 453 | __le64 root_dirid; |
452 | __le64 bytenr; | 454 | __le64 bytenr; |
453 | __le64 byte_limit; | 455 | __le64 byte_limit; |
@@ -1396,10 +1398,14 @@ static inline int btrfs_is_leaf(struct extent_buffer *eb) | |||
1396 | } | 1398 | } |
1397 | 1399 | ||
1398 | /* struct btrfs_root_item */ | 1400 | /* struct btrfs_root_item */ |
1401 | BTRFS_SETGET_FUNCS(disk_root_generation, struct btrfs_root_item, | ||
1402 | generation, 64); | ||
1399 | BTRFS_SETGET_FUNCS(disk_root_refs, struct btrfs_root_item, refs, 32); | 1403 | BTRFS_SETGET_FUNCS(disk_root_refs, struct btrfs_root_item, refs, 32); |
1400 | BTRFS_SETGET_FUNCS(disk_root_bytenr, struct btrfs_root_item, bytenr, 64); | 1404 | BTRFS_SETGET_FUNCS(disk_root_bytenr, struct btrfs_root_item, bytenr, 64); |
1401 | BTRFS_SETGET_FUNCS(disk_root_level, struct btrfs_root_item, level, 8); | 1405 | BTRFS_SETGET_FUNCS(disk_root_level, struct btrfs_root_item, level, 8); |
1402 | 1406 | ||
1407 | BTRFS_SETGET_STACK_FUNCS(root_generation, struct btrfs_root_item, | ||
1408 | generation, 64); | ||
1403 | BTRFS_SETGET_STACK_FUNCS(root_bytenr, struct btrfs_root_item, bytenr, 64); | 1409 | BTRFS_SETGET_STACK_FUNCS(root_bytenr, struct btrfs_root_item, bytenr, 64); |
1404 | BTRFS_SETGET_STACK_FUNCS(root_level, struct btrfs_root_item, level, 8); | 1410 | BTRFS_SETGET_STACK_FUNCS(root_level, struct btrfs_root_item, level, 8); |
1405 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); | 1411 | BTRFS_SETGET_STACK_FUNCS(root_dirid, struct btrfs_root_item, root_dirid, 64); |
@@ -1416,6 +1422,8 @@ BTRFS_SETGET_STACK_FUNCS(super_generation, struct btrfs_super_block, | |||
1416 | BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64); | 1422 | BTRFS_SETGET_STACK_FUNCS(super_root, struct btrfs_super_block, root, 64); |
1417 | BTRFS_SETGET_STACK_FUNCS(super_sys_array_size, | 1423 | BTRFS_SETGET_STACK_FUNCS(super_sys_array_size, |
1418 | struct btrfs_super_block, sys_chunk_array_size, 32); | 1424 | struct btrfs_super_block, sys_chunk_array_size, 32); |
1425 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root_generation, | ||
1426 | struct btrfs_super_block, chunk_root_generation, 64); | ||
1419 | BTRFS_SETGET_STACK_FUNCS(super_root_level, struct btrfs_super_block, | 1427 | BTRFS_SETGET_STACK_FUNCS(super_root_level, struct btrfs_super_block, |
1420 | root_level, 8); | 1428 | root_level, 8); |
1421 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root, struct btrfs_super_block, | 1429 | BTRFS_SETGET_STACK_FUNCS(super_chunk_root, struct btrfs_super_block, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d1137d7ea8d4..94b4e50f6b2c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -832,6 +832,7 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
832 | { | 832 | { |
833 | int ret; | 833 | int ret; |
834 | u32 blocksize; | 834 | u32 blocksize; |
835 | u64 generation; | ||
835 | 836 | ||
836 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 837 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
837 | tree_root->sectorsize, tree_root->stripesize, | 838 | tree_root->sectorsize, tree_root->stripesize, |
@@ -840,9 +841,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
840 | &root->root_item, &root->root_key); | 841 | &root->root_item, &root->root_key); |
841 | BUG_ON(ret); | 842 | BUG_ON(ret); |
842 | 843 | ||
844 | generation = btrfs_root_generation(&root->root_item); | ||
843 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 845 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
844 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 846 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
845 | blocksize, 0); | 847 | blocksize, generation); |
846 | BUG_ON(!root->node); | 848 | BUG_ON(!root->node); |
847 | return 0; | 849 | return 0; |
848 | } | 850 | } |
@@ -929,6 +931,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
929 | struct btrfs_path *path; | 931 | struct btrfs_path *path; |
930 | struct extent_buffer *l; | 932 | struct extent_buffer *l; |
931 | u64 highest_inode; | 933 | u64 highest_inode; |
934 | u64 generation; | ||
932 | u32 blocksize; | 935 | u32 blocksize; |
933 | int ret = 0; | 936 | int ret = 0; |
934 | 937 | ||
@@ -970,9 +973,10 @@ out: | |||
970 | kfree(root); | 973 | kfree(root); |
971 | return ERR_PTR(ret); | 974 | return ERR_PTR(ret); |
972 | } | 975 | } |
976 | generation = btrfs_root_generation(&root->root_item); | ||
973 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 977 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
974 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 978 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
975 | blocksize, 0); | 979 | blocksize, generation); |
976 | BUG_ON(!root->node); | 980 | BUG_ON(!root->node); |
977 | insert: | 981 | insert: |
978 | if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { | 982 | if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { |
@@ -1357,6 +1361,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1357 | u32 leafsize; | 1361 | u32 leafsize; |
1358 | u32 blocksize; | 1362 | u32 blocksize; |
1359 | u32 stripesize; | 1363 | u32 stripesize; |
1364 | u64 generation; | ||
1360 | struct buffer_head *bh; | 1365 | struct buffer_head *bh; |
1361 | struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), | 1366 | struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), |
1362 | GFP_NOFS); | 1367 | GFP_NOFS); |
@@ -1596,13 +1601,14 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1596 | 1601 | ||
1597 | blocksize = btrfs_level_size(tree_root, | 1602 | blocksize = btrfs_level_size(tree_root, |
1598 | btrfs_super_chunk_root_level(disk_super)); | 1603 | btrfs_super_chunk_root_level(disk_super)); |
1604 | generation = btrfs_super_chunk_root_generation(disk_super); | ||
1599 | 1605 | ||
1600 | __setup_root(nodesize, leafsize, sectorsize, stripesize, | 1606 | __setup_root(nodesize, leafsize, sectorsize, stripesize, |
1601 | chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID); | 1607 | chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID); |
1602 | 1608 | ||
1603 | chunk_root->node = read_tree_block(chunk_root, | 1609 | chunk_root->node = read_tree_block(chunk_root, |
1604 | btrfs_super_chunk_root(disk_super), | 1610 | btrfs_super_chunk_root(disk_super), |
1605 | blocksize, 0); | 1611 | blocksize, generation); |
1606 | BUG_ON(!chunk_root->node); | 1612 | BUG_ON(!chunk_root->node); |
1607 | 1613 | ||
1608 | read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid, | 1614 | read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid, |
@@ -1618,11 +1624,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1618 | 1624 | ||
1619 | blocksize = btrfs_level_size(tree_root, | 1625 | blocksize = btrfs_level_size(tree_root, |
1620 | btrfs_super_root_level(disk_super)); | 1626 | btrfs_super_root_level(disk_super)); |
1621 | 1627 | generation = btrfs_super_generation(disk_super); | |
1622 | 1628 | ||
1623 | tree_root->node = read_tree_block(tree_root, | 1629 | tree_root->node = read_tree_block(tree_root, |
1624 | btrfs_super_root(disk_super), | 1630 | btrfs_super_root(disk_super), |
1625 | blocksize, 0); | 1631 | blocksize, generation); |
1626 | if (!tree_root->node) | 1632 | if (!tree_root->node) |
1627 | goto fail_sb_buffer; | 1633 | goto fail_sb_buffer; |
1628 | 1634 | ||
@@ -1672,15 +1678,16 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1672 | log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); | 1678 | log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); |
1673 | 1679 | ||
1674 | log_tree_root->node = read_tree_block(tree_root, bytenr, | 1680 | log_tree_root->node = read_tree_block(tree_root, bytenr, |
1675 | blocksize, 0); | 1681 | blocksize, |
1682 | generation + 1); | ||
1676 | ret = btrfs_recover_log_trees(log_tree_root); | 1683 | ret = btrfs_recover_log_trees(log_tree_root); |
1677 | BUG_ON(ret); | 1684 | BUG_ON(ret); |
1678 | } | 1685 | } |
1686 | fs_info->last_trans_committed = btrfs_super_generation(disk_super); | ||
1679 | 1687 | ||
1680 | ret = btrfs_cleanup_reloc_trees(tree_root); | 1688 | ret = btrfs_cleanup_reloc_trees(tree_root); |
1681 | BUG_ON(ret); | 1689 | BUG_ON(ret); |
1682 | 1690 | ||
1683 | fs_info->last_trans_committed = btrfs_super_generation(disk_super); | ||
1684 | return tree_root; | 1691 | return tree_root; |
1685 | 1692 | ||
1686 | fail_cleaner: | 1693 | fail_cleaner: |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 564260872c7e..155c8dc56a22 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4428,6 +4428,7 @@ static int noinline init_reloc_tree(struct btrfs_trans_handle *trans, | |||
4428 | btrfs_set_root_refs(root_item, 0); | 4428 | btrfs_set_root_refs(root_item, 0); |
4429 | btrfs_set_root_bytenr(root_item, eb->start); | 4429 | btrfs_set_root_bytenr(root_item, eb->start); |
4430 | btrfs_set_root_level(root_item, btrfs_header_level(eb)); | 4430 | btrfs_set_root_level(root_item, btrfs_header_level(eb)); |
4431 | btrfs_set_root_generation(root_item, trans->transid); | ||
4431 | 4432 | ||
4432 | btrfs_tree_unlock(eb); | 4433 | btrfs_tree_unlock(eb); |
4433 | free_extent_buffer(eb); | 4434 | free_extent_buffer(eb); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 1136ce2febcc..fd3c8b5676c1 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -108,6 +108,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
108 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | 108 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); |
109 | 109 | ||
110 | btrfs_set_root_bytenr(&root_item, leaf->start); | 110 | btrfs_set_root_bytenr(&root_item, leaf->start); |
111 | btrfs_set_root_generation(&root_item, trans->transid); | ||
111 | btrfs_set_root_level(&root_item, 0); | 112 | btrfs_set_root_level(&root_item, 0); |
112 | btrfs_set_root_refs(&root_item, 1); | 113 | btrfs_set_root_refs(&root_item, 1); |
113 | btrfs_set_root_used(&root_item, 0); | 114 | btrfs_set_root_used(&root_item, 0); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 48b455fdaac5..924af6f2aeac 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -439,6 +439,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
439 | root->node->start); | 439 | root->node->start); |
440 | btrfs_set_root_level(&root->root_item, | 440 | btrfs_set_root_level(&root->root_item, |
441 | btrfs_header_level(root->node)); | 441 | btrfs_header_level(root->node)); |
442 | btrfs_set_root_generation(&root->root_item, trans->transid); | ||
442 | ret = btrfs_update_root(trans, tree_root, | 443 | ret = btrfs_update_root(trans, tree_root, |
443 | &root->root_key, | 444 | &root->root_key, |
444 | &root->root_item); | 445 | &root->root_item); |
@@ -456,6 +457,12 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | |||
456 | { | 457 | { |
457 | struct btrfs_fs_info *fs_info = root->fs_info; | 458 | struct btrfs_fs_info *fs_info = root->fs_info; |
458 | struct list_head *next; | 459 | struct list_head *next; |
460 | struct extent_buffer *eb; | ||
461 | |||
462 | eb = btrfs_lock_root_node(fs_info->tree_root); | ||
463 | btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb, 0); | ||
464 | btrfs_tree_unlock(eb); | ||
465 | free_extent_buffer(eb); | ||
459 | 466 | ||
460 | while(!list_empty(&fs_info->dirty_cowonly_roots)) { | 467 | while(!list_empty(&fs_info->dirty_cowonly_roots)) { |
461 | next = fs_info->dirty_cowonly_roots.next; | 468 | next = fs_info->dirty_cowonly_roots.next; |
@@ -559,6 +566,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans, | |||
559 | root->node->start); | 566 | root->node->start); |
560 | btrfs_set_root_level(&root->root_item, | 567 | btrfs_set_root_level(&root->root_item, |
561 | btrfs_header_level(root->node)); | 568 | btrfs_header_level(root->node)); |
569 | btrfs_set_root_generation(&root->root_item, | ||
570 | root->root_key.offset); | ||
571 | |||
562 | err = btrfs_insert_root(trans, root->fs_info->tree_root, | 572 | err = btrfs_insert_root(trans, root->fs_info->tree_root, |
563 | &root->root_key, | 573 | &root->root_key, |
564 | &root->root_item); | 574 | &root->root_item); |
@@ -756,6 +766,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
756 | 766 | ||
757 | btrfs_set_root_bytenr(new_root_item, tmp->start); | 767 | btrfs_set_root_bytenr(new_root_item, tmp->start); |
758 | btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); | 768 | btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); |
769 | btrfs_set_root_generation(new_root_item, trans->transid); | ||
759 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 770 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
760 | new_root_item); | 771 | new_root_item); |
761 | btrfs_tree_unlock(tmp); | 772 | btrfs_tree_unlock(tmp); |
@@ -946,6 +957,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
946 | chunk_root->node->start); | 957 | chunk_root->node->start); |
947 | btrfs_set_super_chunk_root_level(&root->fs_info->super_copy, | 958 | btrfs_set_super_chunk_root_level(&root->fs_info->super_copy, |
948 | btrfs_header_level(chunk_root->node)); | 959 | btrfs_header_level(chunk_root->node)); |
960 | btrfs_set_super_chunk_root_generation(&root->fs_info->super_copy, | ||
961 | btrfs_header_generation(chunk_root->node)); | ||
949 | 962 | ||
950 | if (!root->fs_info->log_root_recovering) { | 963 | if (!root->fs_info->log_root_recovering) { |
951 | btrfs_set_super_log_root(&root->fs_info->super_copy, 0); | 964 | btrfs_set_super_log_root(&root->fs_info->super_copy, 0); |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 835daed5561f..e0201c3a7dc9 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -117,6 +117,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | |||
117 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | 117 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); |
118 | 118 | ||
119 | btrfs_set_root_bytenr(&root_item, leaf->start); | 119 | btrfs_set_root_bytenr(&root_item, leaf->start); |
120 | btrfs_set_root_generation(&root_item, trans->transid); | ||
120 | btrfs_set_root_level(&root_item, 0); | 121 | btrfs_set_root_level(&root_item, 0); |
121 | btrfs_set_root_refs(&root_item, 0); | 122 | btrfs_set_root_refs(&root_item, 0); |
122 | btrfs_set_root_used(&root_item, 0); | 123 | btrfs_set_root_used(&root_item, 0); |
@@ -2065,6 +2066,7 @@ static int update_log_root(struct btrfs_trans_handle *trans, | |||
2065 | return 0; | 2066 | return 0; |
2066 | 2067 | ||
2067 | btrfs_set_root_bytenr(&log->root_item, log->node->start); | 2068 | btrfs_set_root_bytenr(&log->root_item, log->node->start); |
2069 | btrfs_set_root_generation(&log->root_item, trans->transid); | ||
2068 | btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); | 2070 | btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); |
2069 | ret = btrfs_update_root(trans, log->fs_info->log_root_tree, | 2071 | ret = btrfs_update_root(trans, log->fs_info->log_root_tree, |
2070 | &log->root_key, &log->root_item); | 2072 | &log->root_key, &log->root_item); |