On Tue, Mar 12, 2013 at 01:38:17PM -0400, Josef Bacik wrote: > --- a/cmds-restore.c > +++ b/cmds-restore.c > @@ -839,27 +839,67 @@ static int do_list_roots(struct btrfs_root *root) > static struct btrfs_root *open_fs(const char *dev, u64 root_location, > int super_mirror, int list_roots) > { > + struct btrfs_fs_info *fs_info = NULL; > struct btrfs_root *root = NULL; > u64 bytenr; > int i; > > for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) { > bytenr = btrfs_sb_offset(i); > - root = open_ctree_recovery(dev, bytenr, root_location); > - if (root) > + fs_info = open_ctree_fs_info(dev, bytenr, root_location, 0, 1); > + if (fs_info) > break; > fprintf(stderr, "Could not open root, trying backup super\n"); > } > > - if (root && list_roots) { > - int ret = do_list_roots(root); > - if (ret) { > + if (!fs_info) > + return NULL; > + > + /* > + * All we really need to succeed is reading the chunk tree, everything > + * else we can do by hand, since we only need to read the tree root and > + * the fs_root. > + */ > + if (!extent_buffer_uptodate(fs_info->tree_root->node)) { > + u64 generation; > + > + root = fs_info->tree_root; > + if (!root_location) > + root_location = btrfs_super_root(fs_info->super_copy); > + generation = btrfs_super_generation(fs_info->super_copy); > + root->node = read_tree_block(root, root_location, > + root->leafsize, generation); > + if (!extent_buffer_uptodate(root->node)) { > + fprintf(stderr, "Error opening tree root\n"); > close_ctree(root); > + return NULL; > + } > + } > + > + if (!list_roots && !fs_info->fs_root) { > + struct btrfs_key key; > + > + key.objectid = BTRFS_FS_TREE_OBJECTID; > + key.type = BTRFS_ROOT_ITEM_KEY; > + key.offset = (u64)-1; > + fs_info->fs_root = btrfs_read_fs_root_no_cache(fs_info, &key); > + if (IS_ERR(fs_info->fs_root)) { > + fprintf(stderr, "Couldn't read fs root: %ld\n", > + PTR_ERR(fs_info->fs_root)); > + close_ctree(fs_info->tree_root); > + return NULL; > + } > + } > + > + if (list_roots) { > + int ret = do_list_roots(fs_info->tree_root); > + if (ret) { > + close_ctree(fs_info->tree_root); > root = NULL;
Setting root to NULL here has no effect, I wonder if this should be 'return NULL' instead, or if it's really ok to return fs_info->fs_root even after close_ctree() which calls free_fs_roots and other cleanups. > } > } > > - return root; > + return fs_info->fs_root; > } -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html