From 4735d0bb8248a3900f420cb9144e4f7969f0b44d Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 28 Oct 2013 14:28:43 -0400 Subject: Btrfs-progs: rework open_ctree to take flags, add a new one V2 So I needed to add a flag to not try to read block groups when doing --init-extent-tree since we could hang there, but that meant adding a whole other 0/1 type flag to open_ctree_fs_info. So instead I've converted it all over to using a flags setting and added the flag that I needed. This has been tested with xfstests and make test. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- btrfs-convert.c | 6 +-- btrfs-corrupt-block.c | 2 +- btrfs-debug-tree.c | 2 +- btrfs-image.c | 9 ++++- btrfs-zero-log.c | 2 +- btrfstune.c | 2 +- cmds-check.c | 14 +++---- cmds-chunk.c | 2 +- cmds-restore.c | 3 +- disk-io.c | 106 ++++++++++++++------------------------------------ disk-io.h | 26 +++++++------ mkfs.c | 2 +- quick-test.c | 10 ++--- super-recover.c | 4 +- utils.c | 2 +- 15 files changed, 78 insertions(+), 114 deletions(-) diff --git a/btrfs-convert.c b/btrfs-convert.c index 26c7b5fd..ae10eed0 100644 --- a/btrfs-convert.c +++ b/btrfs-convert.c @@ -2256,7 +2256,7 @@ static int do_convert(const char *devname, int datacsum, int packing, fprintf(stderr, "unable to update system chunk\n"); goto fail; } - root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR); + root = open_ctree_fd(fd, devname, super_bytenr, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; @@ -2317,7 +2317,7 @@ static int do_convert(const char *devname, int datacsum, int packing, goto fail; } - root = open_ctree_fd(fd, devname, 0, O_RDWR); + root = open_ctree_fd(fd, devname, 0, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; @@ -2418,7 +2418,7 @@ static int do_rollback(const char *devname, int force) fprintf(stderr, "unable to open %s\n", devname); goto fail; } - root = open_ctree_fd(fd, devname, 0, O_RDWR); + root = open_ctree_fd(fd, devname, 0, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index b40a529b..f0c14a9d 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -799,7 +799,7 @@ int main(int ac, char **av) radix_tree_init(); cache_tree_init(&root_cache); - root = open_ctree(dev, 0, 1); + root = open_ctree(dev, 0, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); exit(1); diff --git a/btrfs-debug-tree.c b/btrfs-debug-tree.c index 4a9d89de..4a837704 100644 --- a/btrfs-debug-tree.c +++ b/btrfs-debug-tree.c @@ -171,7 +171,7 @@ int main(int ac, char **av) if (ac != 1) print_usage(); - info = open_ctree_fs_info(av[optind], 0, 0, 0, 1, 0); + info = open_ctree_fs_info(av[optind], 0, 0, OPEN_CTREE_PARTIAL); if (!info) { fprintf(stderr, "unable to open %s\n", av[optind]); exit(1); diff --git a/btrfs-image.c b/btrfs-image.c index 40ed4831..7bcfc069 100644 --- a/btrfs-image.c +++ b/btrfs-image.c @@ -2267,7 +2267,10 @@ static int __restore_metadump(const char *input, FILE *out, int old_restore, /* NOTE: open with write mode */ if (fixup_offset) { BUG_ON(!target); - info = open_ctree_fs_info_restore(target, 0, 0, 1, 1); + info = open_ctree_fs_info(target, 0, 0, + OPEN_CTREE_WRITES | + OPEN_CTREE_RESTORE | + OPEN_CTREE_PARTIAL); if (!info) { fprintf(stderr, "%s: open ctree failed\n", __func__); ret = -EIO; @@ -2555,7 +2558,9 @@ int main(int argc, char *argv[]) u64 total_devs; int i; - info = open_ctree_fs_info_restore(target, 0, 0, 0, 1); + info = open_ctree_fs_info(target, 0, 0, + OPEN_CTREE_PARTIAL | + OPEN_CTREE_RESTORE); if (!info) { int e = errno; fprintf(stderr, "unable to open %s error = %s\n", diff --git a/btrfs-zero-log.c b/btrfs-zero-log.c index 432adff4..ab7f418a 100644 --- a/btrfs-zero-log.c +++ b/btrfs-zero-log.c @@ -60,7 +60,7 @@ int main(int ac, char **av) goto out; } - root = open_ctree(av[1], 0, 1); + root = open_ctree(av[1], 0, OPEN_CTREE_WRITES); if (root == NULL) return 1; diff --git a/btrfstune.c b/btrfstune.c index 1cf6a689..50724bae 100644 --- a/btrfstune.c +++ b/btrfstune.c @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) return 1; } - root = open_ctree(device, 0, 1); + root = open_ctree(device, 0, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); diff --git a/cmds-check.c b/cmds-check.c index 3453cac2..37348a94 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -6045,13 +6045,12 @@ int cmd_check(int argc, char **argv) struct btrfs_fs_info *info; u64 bytenr = 0; char uuidbuf[37]; - int backup_root = 0; int ret; int num; int option_index = 0; int init_csum_tree = 0; int init_extent_tree = 0; - int rw = 0; + enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_PARTIAL; while(1) { int c; @@ -6062,7 +6061,7 @@ int cmd_check(int argc, char **argv) switch(c) { case 'a': /* ignored */ break; case 'b': - backup_root = 1; + ctree_flags |= OPEN_CTREE_BACKUP_ROOT; break; case 's': num = atol(optarg); @@ -6077,14 +6076,15 @@ int cmd_check(int argc, char **argv) if (option_index == 1) { printf("enabling repair mode\n"); repair = 1; - rw = 1; + ctree_flags |= OPEN_CTREE_WRITES; } else if (option_index == 2) { printf("Creating a new CRC tree\n"); init_csum_tree = 1; - rw = 1; + ctree_flags |= OPEN_CTREE_WRITES; } else if (option_index == 3) { init_extent_tree = 1; - rw = 1; + ctree_flags |= (OPEN_CTREE_WRITES | + OPEN_CTREE_NO_BLOCK_GROUPS); repair = 1; } @@ -6105,7 +6105,7 @@ int cmd_check(int argc, char **argv) return -EBUSY; } - info = open_ctree_fs_info(argv[optind], bytenr, 0, rw, 1, backup_root); + info = open_ctree_fs_info(argv[optind], bytenr, 0, ctree_flags); if (!info) { fprintf(stderr, "Couldn't open file system\n"); return -EIO; diff --git a/cmds-chunk.c b/cmds-chunk.c index 4c2f3ed1..4d7fce03 100644 --- a/cmds-chunk.c +++ b/cmds-chunk.c @@ -1231,7 +1231,7 @@ open_ctree_with_broken_chunk(struct recover_control *rc) if (ret) goto out_cleanup; - ret = btrfs_setup_all_roots(fs_info, 0, 0); + ret = btrfs_setup_all_roots(fs_info, 0, 0, 0); if (ret) goto out_failed; diff --git a/cmds-restore.c b/cmds-restore.c index e315d2e6..1748262b 100644 --- a/cmds-restore.c +++ b/cmds-restore.c @@ -974,7 +974,8 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); - fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0, 1, 0); + fs_info = open_ctree_fs_info(dev, bytenr, root_location, + OPEN_CTREE_PARTIAL); if (fs_info) break; fprintf(stderr, "Could not open root, trying backup super\n"); diff --git a/disk-io.c b/disk-io.c index 733714df..0af38985 100644 --- a/disk-io.c +++ b/disk-io.c @@ -827,8 +827,8 @@ static int find_best_backup_root(struct btrfs_super_block *super) return best_index; } -int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, - u64 root_tree_bytenr, int partial, int backup_root) +int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr, + enum btrfs_open_ctree_flags flags) { struct btrfs_super_block *sb = fs_info->super_copy; struct btrfs_root *root; @@ -852,9 +852,9 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, blocksize = btrfs_level_size(root, btrfs_super_root_level(sb)); generation = btrfs_super_generation(sb); - if (!root_tree_bytenr && !backup_root) { + if (!root_tree_bytenr && !(flags & OPEN_CTREE_BACKUP_ROOT)) { root_tree_bytenr = btrfs_super_root(sb); - } else if (backup_root) { + } else if (flags & OPEN_CTREE_BACKUP_ROOT) { struct btrfs_root_backup *backup; int index = find_best_backup_root(sb); if (index >= BTRFS_NUM_BACKUP_ROOTS) { @@ -893,7 +893,7 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, fs_info->csum_root); if (ret) { printk("Couldn't setup csum tree\n"); - if (!partial) + if (!(flags & OPEN_CTREE_PARTIAL)) return -EIO; } fs_info->csum_root->track_dirty = 1; @@ -906,7 +906,9 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, fs_info->generation = generation; fs_info->last_trans_committed = generation; - btrfs_read_block_groups(fs_info->tree_root); + if (extent_buffer_uptodate(fs_info->extent_root->node) && + !(flags & OPEN_CTREE_NO_BLOCK_GROUPS)) + btrfs_read_block_groups(fs_info->tree_root); key.objectid = BTRFS_FS_TREE_OBJECTID; key.type = BTRFS_ROOT_ITEM_KEY; @@ -1034,10 +1036,8 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info) static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr, - u64 root_tree_bytenr, int writes, - int partial, int restore, - int recover_super, - int backup_root) + u64 root_tree_bytenr, + enum btrfs_open_ctree_flags flags) { struct btrfs_fs_info *fs_info; struct btrfs_super_block *disk_super; @@ -1052,21 +1052,21 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, if (posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED)) fprintf(stderr, "Warning, could not drop caches\n"); - fs_info = btrfs_new_fs_info(writes, sb_bytenr); + fs_info = btrfs_new_fs_info(flags & OPEN_CTREE_WRITES, sb_bytenr); if (!fs_info) { fprintf(stderr, "Failed to allocate memory for fs_info\n"); return NULL; } - if (restore) + if (flags & OPEN_CTREE_RESTORE) fs_info->on_restoring = 1; ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr, - !recover_super); + !(flags & OPEN_CTREE_RECOVER_SUPER)); if (ret) goto out; fs_info->fs_devices = fs_devices; - if (writes) + if (flags & OPEN_CTREE_WRITES) ret = btrfs_open_devices(fs_devices, O_RDWR); else ret = btrfs_open_devices(fs_devices, O_RDONLY); @@ -1075,7 +1075,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, disk_super = fs_info->super_copy; - if (!recover_super) + if (!(flags & OPEN_CTREE_RECOVER_SUPER)) ret = btrfs_read_dev_super(fs_devices->latest_bdev, disk_super, sb_bytenr); else @@ -1087,7 +1087,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE); - ret = btrfs_check_fs_compatibility(fs_info->super_copy, writes); + ret = btrfs_check_fs_compatibility(fs_info->super_copy, + flags & OPEN_CTREE_WRITES); if (ret) goto out_devices; @@ -1100,15 +1101,14 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, (unsigned long)btrfs_header_chunk_tree_uuid(eb), BTRFS_UUID_SIZE); - ret = btrfs_setup_all_roots(fs_info, root_tree_bytenr, partial, - backup_root); + ret = btrfs_setup_all_roots(fs_info, root_tree_bytenr, flags); if (ret) goto out_failed; return fs_info; out_failed: - if (partial) + if (flags & OPEN_CTREE_PARTIAL) return fs_info; out_chunk: btrfs_release_all_roots(fs_info); @@ -1120,90 +1120,44 @@ out: return NULL; } -struct btrfs_fs_info *open_ctree_fs_info_restore(const char *filename, - u64 sb_bytenr, u64 root_tree_bytenr, - int writes, int partial) -{ - int fp; - struct btrfs_fs_info *info; - int flags = O_CREAT | O_RDWR; - int restore = 1; - - if (!writes) - flags = O_RDONLY; - - fp = open(filename, flags, 0600); - if (fp < 0) { - fprintf (stderr, "Could not open %s\n", filename); - return NULL; - } - info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, - writes, partial, restore, 0, 0); - close(fp); - return info; -} - struct btrfs_fs_info *open_ctree_fs_info(const char *filename, u64 sb_bytenr, u64 root_tree_bytenr, - int writes, int partial, - int backup_root) + enum btrfs_open_ctree_flags flags) { int fp; struct btrfs_fs_info *info; - int flags = O_CREAT | O_RDWR; + int oflags = O_CREAT | O_RDWR; - if (!writes) - flags = O_RDONLY; + if (!(flags & OPEN_CTREE_WRITES)) + oflags = O_RDONLY; - fp = open(filename, flags, 0600); + fp = open(filename, oflags, 0600); if (fp < 0) { fprintf (stderr, "Could not open %s\n", filename); return NULL; } info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, - writes, partial, 0, 0, backup_root); + flags); close(fp); return info; } -struct btrfs_root *open_ctree_with_broken_super(const char *filename, - u64 sb_bytenr, int writes) -{ - int fp; - struct btrfs_fs_info *info; - int flags = O_CREAT | O_RDWR; - - if (!writes) - flags = O_RDONLY; - - fp = open(filename, flags, 0600); - if (fp < 0) { - fprintf(stderr, "Could not open %s\n", filename); - return NULL; - } - info = __open_ctree_fd(fp, filename, sb_bytenr, 0, - writes, 0, 0, 1, 0); - close(fp); - if (info) - return info->fs_root; - return NULL; -} - -struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes) +struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, + enum btrfs_open_ctree_flags flags) { struct btrfs_fs_info *info; - info = open_ctree_fs_info(filename, sb_bytenr, 0, writes, 0, 0); + info = open_ctree_fs_info(filename, sb_bytenr, 0, flags); if (!info) return NULL; return info->fs_root; } struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, - int writes) + enum btrfs_open_ctree_flags flags) { struct btrfs_fs_info *info; - info = __open_ctree_fd(fp, path, sb_bytenr, 0, writes, 0, 0, 0, 0); + info = __open_ctree_fd(fp, path, sb_bytenr, 0, flags); if (!info) return NULL; return info->fs_root; diff --git a/disk-io.h b/disk-io.h index b0292db2..ca6af2d8 100644 --- a/disk-io.h +++ b/disk-io.h @@ -25,6 +25,15 @@ #define BTRFS_SUPER_MIRROR_MAX 3 #define BTRFS_SUPER_MIRROR_SHIFT 12 +enum btrfs_open_ctree_flags { + OPEN_CTREE_WRITES = 1, + OPEN_CTREE_PARTIAL = 2, + OPEN_CTREE_BACKUP_ROOT = 4, + OPEN_CTREE_RECOVER_SUPER = 8, + OPEN_CTREE_RESTORE = 16, + OPEN_CTREE_NO_BLOCK_GROUPS = 32, +}; + static inline u64 btrfs_sb_offset(int mirror) { u64 start = 16 * 1024; @@ -52,8 +61,8 @@ int clean_tree_block(struct btrfs_trans_handle *trans, void btrfs_free_fs_info(struct btrfs_fs_info *fs_info); struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr); int btrfs_check_fs_compatibility(struct btrfs_super_block *sb, int writable); -int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, - u64 root_tree_bytenr, int partial, int backup_root); +int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr, + enum btrfs_open_ctree_flags flags); void btrfs_release_all_roots(struct btrfs_fs_info *fs_info); void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info); int btrfs_scan_fs_devices(int fd, const char *path, @@ -61,18 +70,13 @@ int btrfs_scan_fs_devices(int fd, const char *path, int run_ioctl); int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info); -struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes); +struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, + enum btrfs_open_ctree_flags flags); struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, - int writes); -struct btrfs_fs_info *open_ctree_fs_info_restore(const char *filename, - u64 sb_bytenr, u64 root_tree_bytenr, - int writes, int partial); + enum btrfs_open_ctree_flags flags); struct btrfs_fs_info *open_ctree_fs_info(const char *filename, u64 sb_bytenr, u64 root_tree_bytenr, - int writes, int partial, - int backup_root); -struct btrfs_root *open_ctree_with_broken_super(const char *filename, - u64 sb_bytenr, int writes); + enum btrfs_open_ctree_flags flags); int close_ctree(struct btrfs_root *root); int write_all_supers(struct btrfs_root *root); int write_ctree_super(struct btrfs_trans_handle *trans, diff --git a/mkfs.c b/mkfs.c index d5767978..46ee5c08 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1476,7 +1476,7 @@ int main(int ac, char **av) exit(1); } - root = open_ctree(file, 0, O_RDWR); + root = open_ctree(file, 0, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); close(fd); diff --git a/quick-test.c b/quick-test.c index b12b9ef9..5dfb2feb 100644 --- a/quick-test.c +++ b/quick-test.c @@ -51,7 +51,7 @@ int main(int ac, char **av) { radix_tree_init(); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); exit(1); @@ -78,7 +78,7 @@ int main(int ac, char **av) { btrfs_commit_transaction(trans, root); close_ctree(root); exit(1); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); exit(1); @@ -101,7 +101,7 @@ int main(int ac, char **av) { } close_ctree(root); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); exit(1); @@ -133,7 +133,7 @@ int main(int ac, char **av) { btrfs_commit_transaction(trans, root); close_ctree(root); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); exit(1); @@ -153,7 +153,7 @@ int main(int ac, char **av) { btrfs_commit_transaction(trans, root); close_ctree(root); - root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR); + root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES); if (!root) { fprintf(stderr, "Open ctree failed\n"); exit(1); diff --git a/super-recover.c b/super-recover.c index 5920ea6b..a6271a27 100644 --- a/super-recover.c +++ b/super-recover.c @@ -323,8 +323,8 @@ int btrfs_recover_superblocks(const char *dname, } } record = recover_get_good_super(&recover); - root = open_ctree_with_broken_super(record->device_name, - record->bytenr, 1); + root = open_ctree(record->device_name, record->bytenr, + OPEN_CTREE_RECOVER_SUPER | OPEN_CTREE_WRITES); if (!root) { ret = 3; goto no_recover; diff --git a/utils.c b/utils.c index 5bedd97f..60d2c3a6 100644 --- a/utils.c +++ b/utils.c @@ -1302,7 +1302,7 @@ static int set_label_unmounted(const char *dev, const char *label) /* Open the super_block at the default location * and as read-write. */ - root = open_ctree(dev, 0, 1); + root = open_ctree(dev, 0, OPEN_CTREE_WRITES); if (!root) /* errors are printed by open_ctree() */ return -1; -- cgit v1.2.3