Btrfs-progs: rework open_ctree to take flags, add a new one V2
authorJosef Bacik <jbacik@fusionio.com>
Mon, 28 Oct 2013 18:28:43 +0000 (14:28 -0400)
committerChris Mason <chris.mason@fusionio.com>
Thu, 7 Nov 2013 21:10:40 +0000 (16:10 -0500)
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 <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
15 files changed:
btrfs-convert.c
btrfs-corrupt-block.c
btrfs-debug-tree.c
btrfs-image.c
btrfs-zero-log.c
btrfstune.c
cmds-check.c
cmds-chunk.c
cmds-restore.c
disk-io.c
disk-io.h
mkfs.c
quick-test.c
super-recover.c
utils.c

index 26c7b5f..ae10eed 100644 (file)
@@ -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;
index b40a529..f0c14a9 100644 (file)
@@ -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);
index 4a9d89d..4a83770 100644 (file)
@@ -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);
index 40ed483..7bcfc06 100644 (file)
@@ -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",
index 432adff..ab7f418 100644 (file)
@@ -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;
index 1cf6a68..50724ba 100644 (file)
@@ -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");
index 3453cac..37348a9 100644 (file)
@@ -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;
index 4c2f3ed..4d7fce0 100644 (file)
@@ -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;
 
index e315d2e..1748262 100644 (file)
@@ -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");
index 733714d..0af3898 100644 (file)
--- 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;
index b0292db..ca6af2d 100644 (file)
--- a/disk-io.h
+++ b/disk-io.h
 #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 d576797..46ee5c0 100644 (file)
--- 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);
index b12b9ef..5dfb2fe 100644 (file)
@@ -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);
index 5920ea6..a6271a2 100644 (file)
@@ -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 5bedd97..60d2c3a 100644 (file)
--- 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;