#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)
ret = check_extents(root);
if (ret)
goto out;
-
ret = check_fs_roots(root);
out:
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;
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
*/
int ret;
int slot;
int extent_only = 0;
+ struct btrfs_root *tree_root_scan;
radix_tree_init();
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];
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)
(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;
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)
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;
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);
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;
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;
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;