diff options
Diffstat (limited to 'disk-io.c')
-rw-r--r-- | disk-io.c | 42 |
1 files changed, 35 insertions, 7 deletions
@@ -982,7 +982,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 partial, int restore, + int recover_super) { struct btrfs_fs_info *fs_info; struct btrfs_super_block *disk_super; @@ -1005,7 +1006,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, if (restore) fs_info->on_restoring = 1; - ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr, 1); + ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr, + !recover_super); if (ret) goto out; @@ -1019,8 +1021,11 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, disk_super = fs_info->super_copy; - ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + if (!recover_super) + ret = btrfs_read_dev_super(fs_devices->latest_bdev, + disk_super, sb_bytenr); + else + ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1078,7 +1083,7 @@ struct btrfs_fs_info *open_ctree_fs_info_restore(const char *filename, return NULL; } info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, - writes, partial, restore); + writes, partial, restore, 0); close(fp); return info; } @@ -1100,11 +1105,34 @@ struct btrfs_fs_info *open_ctree_fs_info(const char *filename, return NULL; } info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, - writes, partial, 0); + writes, partial, 0, 0); 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); + 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_fs_info *info; @@ -1119,7 +1147,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, int writes) { struct btrfs_fs_info *info; - info = __open_ctree_fd(fp, path, sb_bytenr, 0, writes, 0, 0); + info = __open_ctree_fd(fp, path, sb_bytenr, 0, writes, 0, 0, 0); if (!info) return NULL; return info->fs_root; |