+ }
+ if (flags & OPEN_CTREE_RESTORE)
+ fs_info->on_restoring = 1;
+ if (flags & OPEN_CTREE_SUPPRESS_CHECK_BLOCK_ERRORS)
+ fs_info->suppress_check_block_errors = 1;
+ if (flags & OPEN_CTREE_IGNORE_FSID_MISMATCH)
+ fs_info->ignore_fsid_mismatch = 1;
+
+ ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr,
+ (flags & OPEN_CTREE_RECOVER_SUPER),
+ (flags & OPEN_CTREE_NO_DEVICES));
+ if (ret)
+ goto out;
+
+ fs_info->fs_devices = fs_devices;
+ if (flags & OPEN_CTREE_WRITES)
+ oflags = O_RDWR;
+ else
+ oflags = O_RDONLY;
+
+ if (flags & OPEN_CTREE_EXCLUSIVE)
+ oflags |= O_EXCL;
+
+ ret = btrfs_open_devices(fs_devices, oflags);
+ if (ret)
+ goto out;
+
+ disk_super = fs_info->super_copy;
+ if (!(flags & OPEN_CTREE_RECOVER_SUPER))
+ ret = btrfs_read_dev_super(fs_devices->latest_bdev,
+ disk_super, sb_bytenr, 1);
+ else
+ ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr, 0);
+ if (ret) {
+ printk("No valid btrfs found\n");
+ goto out_devices;
+ }
+
+ if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_CHANGING_FSID &&
+ !fs_info->ignore_fsid_mismatch) {
+ fprintf(stderr, "ERROR: Filesystem UUID change in progress\n");
+ goto out_devices;
+ }
+
+ memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE);
+
+ ret = btrfs_check_fs_compatibility(fs_info->super_copy,
+ flags & OPEN_CTREE_WRITES);
+ if (ret)
+ goto out_devices;
+
+ ret = btrfs_setup_chunk_tree_and_device_map(fs_info);
+ if (ret)
+ goto out_chunk;
+
+ eb = fs_info->chunk_root->node;
+ read_extent_buffer(eb, fs_info->chunk_tree_uuid,
+ btrfs_header_chunk_tree_uuid(eb),
+ BTRFS_UUID_SIZE);
+
+ ret = btrfs_setup_all_roots(fs_info, root_tree_bytenr, flags);
+ if (ret && !(flags & __OPEN_CTREE_RETURN_CHUNK_ROOT))
+ goto out_chunk;
+
+ return fs_info;
+
+out_chunk:
+ btrfs_release_all_roots(fs_info);
+ btrfs_cleanup_all_caches(fs_info);
+out_devices:
+ btrfs_close_devices(fs_devices);
+out:
+ btrfs_free_fs_info(fs_info);
+ return NULL;