From: Chris Mason Date: Wed, 15 Apr 2009 18:30:14 +0000 (-0400) Subject: Add scan of the btrfs log tree to btrfs-debug-tree X-Git-Tag: upstream/0.20.rc1~188 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cc04d99e90b4981b188e3308eaa1fee68af08d54;p=platform%2Fupstream%2Fbtrfs-progs.git Add scan of the btrfs log tree to btrfs-debug-tree --- diff --git a/btrfsck.c b/btrfsck.c index 5834ca3..c505088 100644 --- a/btrfsck.c +++ b/btrfsck.c @@ -115,9 +115,9 @@ struct inode_record { #define I_ERR_ODD_FILE_EXTENT (1 << 5) #define I_ERR_BAD_FILE_EXTENT (1 << 6) #define I_ERR_FILE_EXTENT_OVERLAP (1 << 7) -#define I_ERR_FILE_EXTENT_DISCOUNT (1 << 8) +#define I_ERR_FILE_EXTENT_DISCOUNT (1 << 8) // 100 #define I_ERR_DIR_ISIZE_WRONG (1 << 9) -#define I_ERR_FILE_NBYTES_WRONG (1 << 10) +#define I_ERR_FILE_NBYTES_WRONG (1 << 10) // 400 #define I_ERR_ODD_CSUM_ITEM (1 << 11) #define I_ERR_SOME_CSUM_MISSING (1 << 12) @@ -2081,7 +2081,6 @@ int main(int ac, char **av) ret = check_extents(root); if (ret) goto out; - ret = check_fs_roots(root); out: diff --git a/ctree.h b/ctree.h index 593578f..8e7f884 100644 --- a/ctree.h +++ b/ctree.h @@ -479,6 +479,10 @@ struct btrfs_inode_item { struct btrfs_timespec otime; } __attribute__ ((__packed__)); +struct btrfs_dir_log_item { + __le64 end; +} __attribute__ ((__packed__)); + struct btrfs_dir_item { struct btrfs_disk_key location; __le64 transid; @@ -1194,6 +1198,8 @@ static inline void btrfs_set_item_key(struct extent_buffer *eb, write_eb_member(eb, item, struct btrfs_item, key, disk_key); } +BTRFS_SETGET_FUNCS(dir_log_end, struct btrfs_dir_log_item, end, 64); + /* * struct btrfs_root_ref */ diff --git a/debug-tree.c b/debug-tree.c index 53f8be4..0388121 100644 --- a/debug-tree.c +++ b/debug-tree.c @@ -113,6 +113,7 @@ int main(int ac, char **av) int ret; int slot; int extent_only = 0; + struct btrfs_root *tree_root_scan; radix_tree_init(); @@ -147,18 +148,20 @@ int main(int ac, char **av) btrfs_print_tree(root->fs_info->chunk_root, root->fs_info->chunk_root->node); } + tree_root_scan = root->fs_info->tree_root; + btrfs_init_path(&path); +again: key.offset = 0; key.objectid = 0; btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); - ret = btrfs_search_slot(NULL, root->fs_info->tree_root, - &key, &path, 0, 0); + ret = btrfs_search_slot(NULL, tree_root_scan, &key, &path, 0, 0); BUG_ON(ret < 0); while(1) { leaf = path.nodes[0]; slot = path.slots[0]; if (slot >= btrfs_header_nritems(leaf)) { - ret = btrfs_next_leaf(root, &path); + ret = btrfs_next_leaf(tree_root_scan, &path); if (ret != 0) break; leaf = path.nodes[0]; @@ -172,9 +175,9 @@ int main(int ac, char **av) offset = btrfs_item_ptr_offset(leaf, slot); read_extent_buffer(leaf, &ri, offset, sizeof(ri)); - buf = read_tree_block(root->fs_info->tree_root, + buf = read_tree_block(tree_root_scan, btrfs_root_bytenr(&ri), - root->leafsize, 0); + tree_root_scan->leafsize, 0); switch(found_key.objectid) { case BTRFS_ROOT_TREE_OBJECTID: if (!skip) @@ -254,14 +257,21 @@ int main(int ac, char **av) (unsigned long long)found_key.objectid, found_key.type, (unsigned long long)found_key.offset); - btrfs_print_tree(root, buf); + btrfs_print_tree(tree_root_scan, buf); } else if (extent_only && !skip) { - print_extents(root, buf); + print_extents(tree_root_scan, buf); } } path.slots[0]++; } btrfs_release_path(root, &path); + + if (tree_root_scan == root->fs_info->tree_root && + root->fs_info->log_root_tree) { + tree_root_scan = root->fs_info->log_root_tree; + goto again; + } + if (extent_only) return 0; diff --git a/disk-io.c b/disk-io.c index e49c220..239c114 100644 --- a/disk-io.c +++ b/disk-io.c @@ -448,6 +448,33 @@ static int find_and_setup_root(struct btrfs_root *tree_root, return 0; } +static int find_and_setup_log_root(struct btrfs_root *tree_root, + struct btrfs_fs_info *fs_info, + struct btrfs_super_block *disk_super) +{ + u32 blocksize; + u64 blocknr = btrfs_super_log_root(disk_super); + struct btrfs_root *log_root = malloc(sizeof(struct btrfs_root)); + + if (blocknr == 0) + return 0; + + blocksize = btrfs_level_size(tree_root, + btrfs_super_log_root_level(disk_super)); + + __setup_root(tree_root->nodesize, tree_root->leafsize, + tree_root->sectorsize, tree_root->stripesize, + log_root, fs_info, BTRFS_TREE_LOG_OBJECTID); + + log_root->node = read_tree_block(tree_root, blocknr, + blocksize, + btrfs_super_generation(disk_super) + 1); + + fs_info->log_root_tree = log_root; + BUG_ON(!log_root->node); + return 0; +} + int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) { if (root->node) @@ -681,7 +708,8 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, BTRFS_FS_TREE_OBJECTID, root); BUG_ON(ret); root->ref_cows = 1; - fs_info->generation = btrfs_super_generation(disk_super) + 1; + + find_and_setup_log_root(tree_root, fs_info, disk_super); btrfs_read_block_groups(root); fs_info->data_alloc_profile = (u64)-1; @@ -885,6 +913,12 @@ int close_ctree(struct btrfs_root *root) if (root->fs_info->csum_root->node) free_extent_buffer(root->fs_info->csum_root->node); + if (root->fs_info->log_root_tree) { + if (root->fs_info->log_root_tree->node) + free_extent_buffer(root->fs_info->log_root_tree->node); + free(root->fs_info->log_root_tree); + } + close_all_devices(root->fs_info); extent_io_tree_cleanup(&fs_info->extent_cache); extent_io_tree_cleanup(&fs_info->free_space_cache); diff --git a/print-tree.c b/print-tree.c index 52ef7c7..5eb8bfe 100644 --- a/print-tree.c +++ b/print-tree.c @@ -189,6 +189,12 @@ static void print_key_type(u8 type) case BTRFS_DIR_INDEX_KEY: printf("DIR_INDEX"); break; + case BTRFS_DIR_LOG_ITEM_KEY: + printf("DIR_LOG_ITEM"); + break; + case BTRFS_DIR_LOG_INDEX_KEY: + printf("DIR_LOG_INDEX"); + break; case BTRFS_XATTR_ITEM_KEY: printf("XATTR_ITEM"); break; @@ -257,6 +263,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) struct btrfs_disk_key disk_key; struct btrfs_root_item root_item; struct btrfs_block_group_item bg_item; + struct btrfs_dir_log_item *dlog; u32 nr = btrfs_header_nritems(l); u32 type; @@ -299,6 +306,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) di = btrfs_item_ptr(l, i, struct btrfs_dir_item); print_dir_item(l, item, di); break; + case BTRFS_DIR_LOG_INDEX_KEY: + case BTRFS_DIR_LOG_ITEM_KEY: + dlog = btrfs_item_ptr(l, i, struct btrfs_dir_log_item); + printf("\t\tdir log end %Lu\n", + btrfs_dir_log_end(l, dlog)); + break; case BTRFS_ORPHAN_ITEM_KEY: printf("\t\torphan item\n"); break;