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; if (!extent_buffer_uptodate(log_root->node)) return -EIO; return 0; }
static int cmd_rescue_zero_log(int argc, char **argv) { struct btrfs_root *root; struct btrfs_trans_handle *trans; struct btrfs_super_block *sb; char *devname; int ret; clean_args_no_options(argc, argv, cmd_rescue_zero_log_usage); if (check_argc_exact(argc, 2)) usage(cmd_rescue_zero_log_usage); devname = argv[optind]; ret = check_mounted(devname); if (ret < 0) { errno = -ret; error("could not check mount status: %m"); goto out; } else if (ret) { error("%s is currently mounted", devname); ret = -EBUSY; goto out; } root = open_ctree(devname, 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL); if (!root) { error("could not open ctree"); return 1; } sb = root->fs_info->super_copy; printf("Clearing log on %s, previous log_root %llu, level %u\n", devname, (unsigned long long)btrfs_super_log_root(sb), (unsigned)btrfs_super_log_root_level(sb)); trans = btrfs_start_transaction(root, 1); BUG_ON(IS_ERR(trans)); btrfs_set_super_log_root(sb, 0); btrfs_set_super_log_root_level(sb, 0); btrfs_commit_transaction(trans, root); close_ctree(root); out: return !!ret; }
int main(int ac, char **av) { struct btrfs_root *root; struct btrfs_trans_handle *trans; struct btrfs_super_block *sb; int ret; set_argv0(av); if (check_argc_exact(ac, 2)) print_usage(); radix_tree_init(); printf("WARNING: this utility is deprecated, please use 'btrfs rescue zero-log'\n\n"); if ((ret = check_mounted(av[1])) < 0) { fprintf(stderr, "ERROR: could not check mount status: %s\n", strerror(-ret)); goto out; } else if (ret) { fprintf(stderr, "ERROR: %s is currently mounted\n", av[1]); ret = -EBUSY; goto out; } root = open_ctree(av[1], 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL); if (!root) { fprintf(stderr, "ERROR: cannot open ctree\n"); return 1; } sb = root->fs_info->super_copy; printf("Clearing log on %s, previous log_root %llu, level %u\n", av[1], (unsigned long long)btrfs_super_log_root(sb), (unsigned)btrfs_super_log_root_level(sb)); trans = btrfs_start_transaction(root, 1); btrfs_set_super_log_root(root->fs_info->super_copy, 0); btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); btrfs_commit_transaction(trans, root); close_ctree(root); out: return !!ret; }
/* * Get reliable generation and level for given root. * * We have two sources of gen/level: superblock and tree root. * superblock include the following level: * Root, chunk, log * and the following generations: * Root, chunk, uuid * Other gen/leven can only be read from its btrfs_tree_root if possible. * * Currently we only believe things from superblock. */ static void get_root_gen_and_level(u64 objectid, struct btrfs_fs_info *fs_info, u64 *ret_gen, u8 *ret_level) { struct btrfs_super_block *super = fs_info->super_copy; u64 gen = (u64)-1; u8 level = (u8)-1; switch (objectid) { case BTRFS_ROOT_TREE_OBJECTID: level = btrfs_super_root_level(super); gen = btrfs_super_generation(super); break; case BTRFS_CHUNK_TREE_OBJECTID: level = btrfs_super_chunk_root_level(super); gen = btrfs_super_chunk_root_generation(super); break; case BTRFS_TREE_LOG_OBJECTID: level = btrfs_super_log_root_level(super); gen = btrfs_super_log_root_transid(super); break; case BTRFS_UUID_TREE_OBJECTID: gen = btrfs_super_uuid_tree_generation(super); break; } if (gen != (u64)-1) { printf("Superblock thinks the generation is %llu\n", gen); if (ret_gen) *ret_gen = gen; } else { printf("Superblock doesn't contain generation info for root %llu\n", objectid); } if (level != (u8)-1) { printf("Superblock thinks the level is %u\n", level); if (ret_level) *ret_level = level; } else { printf("Superblock doesn't contain the level info for root %llu\n", objectid); } }
static void dump_superblock(struct btrfs_super_block *sb, int full) { int i; char *s, buf[BTRFS_UUID_UNPARSED_SIZE]; u8 *p; printf("csum\t\t\t0x"); for (i = 0, p = sb->csum; i < btrfs_super_csum_size(sb); i++) printf("%02x", p[i]); if (check_csum_sblock(sb, btrfs_super_csum_size(sb))) printf(" [match]"); else printf(" [DON'T MATCH]"); putchar('\n'); printf("bytenr\t\t\t%llu\n", (unsigned long long)btrfs_super_bytenr(sb)); printf("flags\t\t\t0x%llx\n", (unsigned long long)btrfs_super_flags(sb)); print_readable_super_flag(btrfs_super_flags(sb)); printf("magic\t\t\t"); s = (char *) &sb->magic; for (i = 0; i < 8; i++) putchar(isprint(s[i]) ? s[i] : '.'); if (btrfs_super_magic(sb) == BTRFS_MAGIC) printf(" [match]\n"); else printf(" [DON'T MATCH]\n"); uuid_unparse(sb->fsid, buf); printf("fsid\t\t\t%s\n", buf); printf("label\t\t\t"); s = sb->label; for (i = 0; i < BTRFS_LABEL_SIZE && s[i]; i++) putchar(isprint(s[i]) ? s[i] : '.'); putchar('\n'); printf("generation\t\t%llu\n", (unsigned long long)btrfs_super_generation(sb)); printf("root\t\t\t%llu\n", (unsigned long long)btrfs_super_root(sb)); printf("sys_array_size\t\t%llu\n", (unsigned long long)btrfs_super_sys_array_size(sb)); printf("chunk_root_generation\t%llu\n", (unsigned long long)btrfs_super_chunk_root_generation(sb)); printf("root_level\t\t%llu\n", (unsigned long long)btrfs_super_root_level(sb)); printf("chunk_root\t\t%llu\n", (unsigned long long)btrfs_super_chunk_root(sb)); printf("chunk_root_level\t%llu\n", (unsigned long long)btrfs_super_chunk_root_level(sb)); printf("log_root\t\t%llu\n", (unsigned long long)btrfs_super_log_root(sb)); printf("log_root_transid\t%llu\n", (unsigned long long)btrfs_super_log_root_transid(sb)); printf("log_root_level\t\t%llu\n", (unsigned long long)btrfs_super_log_root_level(sb)); printf("total_bytes\t\t%llu\n", (unsigned long long)btrfs_super_total_bytes(sb)); printf("bytes_used\t\t%llu\n", (unsigned long long)btrfs_super_bytes_used(sb)); printf("sectorsize\t\t%llu\n", (unsigned long long)btrfs_super_sectorsize(sb)); printf("nodesize\t\t%llu\n", (unsigned long long)btrfs_super_nodesize(sb)); printf("leafsize\t\t%llu\n", (unsigned long long)btrfs_super_leafsize(sb)); printf("stripesize\t\t%llu\n", (unsigned long long)btrfs_super_stripesize(sb)); printf("root_dir\t\t%llu\n", (unsigned long long)btrfs_super_root_dir(sb)); printf("num_devices\t\t%llu\n", (unsigned long long)btrfs_super_num_devices(sb)); printf("compat_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_compat_flags(sb)); printf("compat_ro_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_compat_ro_flags(sb)); printf("incompat_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_incompat_flags(sb)); print_readable_incompat_flag(btrfs_super_incompat_flags(sb)); printf("csum_type\t\t%llu\n", (unsigned long long)btrfs_super_csum_type(sb)); printf("csum_size\t\t%llu\n", (unsigned long long)btrfs_super_csum_size(sb)); printf("cache_generation\t%llu\n", (unsigned long long)btrfs_super_cache_generation(sb)); printf("uuid_tree_generation\t%llu\n", (unsigned long long)btrfs_super_uuid_tree_generation(sb)); uuid_unparse(sb->dev_item.uuid, buf); printf("dev_item.uuid\t\t%s\n", buf); uuid_unparse(sb->dev_item.fsid, buf); printf("dev_item.fsid\t\t%s %s\n", buf, !memcmp(sb->dev_item.fsid, sb->fsid, BTRFS_FSID_SIZE) ? "[match]" : "[DON'T MATCH]"); printf("dev_item.type\t\t%llu\n", (unsigned long long) btrfs_stack_device_type(&sb->dev_item)); printf("dev_item.total_bytes\t%llu\n", (unsigned long long) btrfs_stack_device_total_bytes(&sb->dev_item)); printf("dev_item.bytes_used\t%llu\n", (unsigned long long) btrfs_stack_device_bytes_used(&sb->dev_item)); printf("dev_item.io_align\t%u\n", (unsigned int) btrfs_stack_device_io_align(&sb->dev_item)); printf("dev_item.io_width\t%u\n", (unsigned int) btrfs_stack_device_io_width(&sb->dev_item)); printf("dev_item.sector_size\t%u\n", (unsigned int) btrfs_stack_device_sector_size(&sb->dev_item)); printf("dev_item.devid\t\t%llu\n", btrfs_stack_device_id(&sb->dev_item)); printf("dev_item.dev_group\t%u\n", (unsigned int) btrfs_stack_device_group(&sb->dev_item)); printf("dev_item.seek_speed\t%u\n", (unsigned int) btrfs_stack_device_seek_speed(&sb->dev_item)); printf("dev_item.bandwidth\t%u\n", (unsigned int) btrfs_stack_device_bandwidth(&sb->dev_item)); printf("dev_item.generation\t%llu\n", (unsigned long long) btrfs_stack_device_generation(&sb->dev_item)); if (full) { printf("sys_chunk_array[%d]:\n", BTRFS_SYSTEM_CHUNK_ARRAY_SIZE); print_sys_chunk_array(sb); printf("backup_roots[%d]:\n", BTRFS_NUM_BACKUP_ROOTS); print_backup_roots(sb); } }
static void dump_superblock(struct btrfs_super_block *sb, int full) { int i; char *s, buf[BTRFS_UUID_UNPARSED_SIZE]; u8 *p; u32 csum_size; u16 csum_type; bool metadata_uuid_present = (btrfs_super_incompat_flags(sb) & BTRFS_FEATURE_INCOMPAT_METADATA_UUID); int cmp_res = 0; csum_type = btrfs_super_csum_type(sb); csum_size = BTRFS_CSUM_SIZE; printf("csum_type\t\t%hu (", csum_type); if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes)) { printf("INVALID"); } else { if (csum_type == BTRFS_CSUM_TYPE_CRC32) { printf("crc32c"); csum_size = btrfs_csum_sizes[csum_type]; } else { printf("unknown"); } } printf(")\n"); printf("csum_size\t\t%llu\n", (unsigned long long)csum_size); printf("csum\t\t\t0x"); for (i = 0, p = sb->csum; i < csum_size; i++) printf("%02x", p[i]); if (csum_type != BTRFS_CSUM_TYPE_CRC32 || csum_size != btrfs_csum_sizes[BTRFS_CSUM_TYPE_CRC32]) printf(" [UNKNOWN CSUM TYPE OR SIZE]"); else if (check_csum_sblock(sb, csum_size)) printf(" [match]"); else printf(" [DON'T MATCH]"); putchar('\n'); printf("bytenr\t\t\t%llu\n", (unsigned long long)btrfs_super_bytenr(sb)); printf("flags\t\t\t0x%llx\n", (unsigned long long)btrfs_super_flags(sb)); print_readable_super_flag(btrfs_super_flags(sb)); printf("magic\t\t\t"); s = (char *) &sb->magic; for (i = 0; i < 8; i++) putchar(isprint(s[i]) ? s[i] : '.'); if (btrfs_super_magic(sb) == BTRFS_MAGIC) printf(" [match]\n"); else printf(" [DON'T MATCH]\n"); uuid_unparse(sb->fsid, buf); printf("fsid\t\t\t%s\n", buf); if (metadata_uuid_present) { uuid_unparse(sb->metadata_uuid, buf); printf("metadata_uuid\t\t%s\n", buf); } else { printf("metadata_uuid\t\t%s\n", buf); } printf("label\t\t\t"); s = sb->label; for (i = 0; i < BTRFS_LABEL_SIZE && s[i]; i++) putchar(isprint(s[i]) ? s[i] : '.'); putchar('\n'); printf("generation\t\t%llu\n", (unsigned long long)btrfs_super_generation(sb)); printf("root\t\t\t%llu\n", (unsigned long long)btrfs_super_root(sb)); printf("sys_array_size\t\t%llu\n", (unsigned long long)btrfs_super_sys_array_size(sb)); printf("chunk_root_generation\t%llu\n", (unsigned long long)btrfs_super_chunk_root_generation(sb)); printf("root_level\t\t%llu\n", (unsigned long long)btrfs_super_root_level(sb)); printf("chunk_root\t\t%llu\n", (unsigned long long)btrfs_super_chunk_root(sb)); printf("chunk_root_level\t%llu\n", (unsigned long long)btrfs_super_chunk_root_level(sb)); printf("log_root\t\t%llu\n", (unsigned long long)btrfs_super_log_root(sb)); printf("log_root_transid\t%llu\n", (unsigned long long)btrfs_super_log_root_transid(sb)); printf("log_root_level\t\t%llu\n", (unsigned long long)btrfs_super_log_root_level(sb)); printf("total_bytes\t\t%llu\n", (unsigned long long)btrfs_super_total_bytes(sb)); printf("bytes_used\t\t%llu\n", (unsigned long long)btrfs_super_bytes_used(sb)); printf("sectorsize\t\t%llu\n", (unsigned long long)btrfs_super_sectorsize(sb)); printf("nodesize\t\t%llu\n", (unsigned long long)btrfs_super_nodesize(sb)); printf("leafsize (deprecated)\t%u\n", le32_to_cpu(sb->__unused_leafsize)); printf("stripesize\t\t%llu\n", (unsigned long long)btrfs_super_stripesize(sb)); printf("root_dir\t\t%llu\n", (unsigned long long)btrfs_super_root_dir(sb)); printf("num_devices\t\t%llu\n", (unsigned long long)btrfs_super_num_devices(sb)); printf("compat_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_compat_flags(sb)); printf("compat_ro_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_compat_ro_flags(sb)); print_readable_compat_ro_flag(btrfs_super_compat_ro_flags(sb)); printf("incompat_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_incompat_flags(sb)); print_readable_incompat_flag(btrfs_super_incompat_flags(sb)); printf("cache_generation\t%llu\n", (unsigned long long)btrfs_super_cache_generation(sb)); printf("uuid_tree_generation\t%llu\n", (unsigned long long)btrfs_super_uuid_tree_generation(sb)); uuid_unparse(sb->dev_item.uuid, buf); printf("dev_item.uuid\t\t%s\n", buf); uuid_unparse(sb->dev_item.fsid, buf); if (metadata_uuid_present) { cmp_res = !memcmp(sb->dev_item.fsid, sb->metadata_uuid, BTRFS_FSID_SIZE); } else { cmp_res = !memcmp(sb->dev_item.fsid, sb->fsid, BTRFS_FSID_SIZE); } printf("dev_item.fsid\t\t%s %s\n", buf, cmp_res ? "[match]" : "[DON'T MATCH]"); printf("dev_item.type\t\t%llu\n", (unsigned long long) btrfs_stack_device_type(&sb->dev_item)); printf("dev_item.total_bytes\t%llu\n", (unsigned long long) btrfs_stack_device_total_bytes(&sb->dev_item)); printf("dev_item.bytes_used\t%llu\n", (unsigned long long) btrfs_stack_device_bytes_used(&sb->dev_item)); printf("dev_item.io_align\t%u\n", (unsigned int) btrfs_stack_device_io_align(&sb->dev_item)); printf("dev_item.io_width\t%u\n", (unsigned int) btrfs_stack_device_io_width(&sb->dev_item)); printf("dev_item.sector_size\t%u\n", (unsigned int) btrfs_stack_device_sector_size(&sb->dev_item)); printf("dev_item.devid\t\t%llu\n", btrfs_stack_device_id(&sb->dev_item)); printf("dev_item.dev_group\t%u\n", (unsigned int) btrfs_stack_device_group(&sb->dev_item)); printf("dev_item.seek_speed\t%u\n", (unsigned int) btrfs_stack_device_seek_speed(&sb->dev_item)); printf("dev_item.bandwidth\t%u\n", (unsigned int) btrfs_stack_device_bandwidth(&sb->dev_item)); printf("dev_item.generation\t%llu\n", (unsigned long long) btrfs_stack_device_generation(&sb->dev_item)); if (full) { printf("sys_chunk_array[%d]:\n", BTRFS_SYSTEM_CHUNK_ARRAY_SIZE); print_sys_chunk_array(sb); printf("backup_roots[%d]:\n", BTRFS_NUM_BACKUP_ROOTS); print_backup_roots(sb); } }