aboutsummaryrefslogtreecommitdiffstats
path: root/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'disk-io.c')
-rw-r--r--disk-io.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/disk-io.c b/disk-io.c
index 6281569..83a2064 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -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;