From 6330d8d3b70c0ad35ce8048ccf69b3e96718ed53 Mon Sep 17 00:00:00 2001 From: David Marcin Date: Mon, 21 Nov 2011 20:31:01 -0600 Subject: [PATCH 26/35] btrfs-progs: Add the ability to use the earliest super found when opening the ctree. Signed-off-by: David Marcin --- convert.c | 6 +++--- disk-io.c | 21 ++++++++++++++------- disk-io.h | 2 +- volumes.c | 9 ++++++++- volumes.h | 6 +++++- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/convert.c b/convert.c index 291dc27..c036f46 100644 --- a/convert.c +++ b/convert.c @@ -2386,7 +2386,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr) 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, O_RDWR, 0); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; @@ -2447,7 +2447,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr) goto fail; } - root = open_ctree_fd(fd, devname, 0, O_RDWR); + root = open_ctree_fd(fd, devname, 0, O_RDWR, 0); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; @@ -2546,7 +2546,7 @@ 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, O_RDWR, 0); if (!root) { fprintf(stderr, "unable to open ctree\n"); goto fail; diff --git a/disk-io.c b/disk-io.c index 408b2d5..a161f15 100644 --- a/disk-io.c +++ b/disk-io.c @@ -580,7 +580,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, return fs_info->dev_root; if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) return fs_info->csum_root; - + BUG_ON(location->objectid == BTRFS_TREE_RELOC_OBJECTID || location->offset != (u64)-1); @@ -602,7 +602,8 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, } struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr, - u64 root_tree_bytenr, int writes) + u64 root_tree_bytenr, int writes, + int use_earliest_bdev) { u32 sectorsize; u32 nodesize; @@ -677,8 +678,14 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr, fs_info->super_bytenr = sb_bytenr; disk_super = &fs_info->super_copy; - ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + if (use_earliest_bdev) { + ret = btrfs_read_dev_super(fs_devices->earliest_bdev, + disk_super, sb_bytenr); + } else { + ret = btrfs_read_dev_super(fs_devices->latest_bdev, + disk_super, sb_bytenr); + } + if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -847,7 +854,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes) fprintf (stderr, "Could not open %s\n", filename); return NULL; } - root = __open_ctree_fd(fp, filename, sb_bytenr, 0, writes); + root = __open_ctree_fd(fp, filename, sb_bytenr, 0, writes, 0); close(fp); return root; @@ -871,9 +878,9 @@ struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr, } struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, - int writes) + int writes, int use_earliest_bdev) { - return __open_ctree_fd(fp, path, sb_bytenr, 0, writes); + return __open_ctree_fd(fp, path, sb_bytenr, 0, writes, use_earliest_bdev); } int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) diff --git a/disk-io.h b/disk-io.h index 2048fcf..8fdcd91 100644 --- a/disk-io.h +++ b/disk-io.h @@ -45,7 +45,7 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf); struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes); struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, - int writes); + int writes, int use_earliest_bdev); struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr, u64 root_tree_bytenr); int close_ctree(struct btrfs_root *root); diff --git a/volumes.c b/volumes.c index 03bfb8c..cde20ad 100644 --- a/volumes.c +++ b/volumes.c @@ -99,6 +99,8 @@ static int device_list_add(const char *path, memcpy(fs_devices->fsid, disk_super->fsid, BTRFS_FSID_SIZE); fs_devices->latest_devid = devid; fs_devices->latest_trans = found_transid; + fs_devices->earliest_devid = devid; + fs_devices->earliest_trans = found_transid; fs_devices->lowest_devid = (u64)-1; device = NULL; } else { @@ -133,8 +135,11 @@ static int device_list_add(const char *path, if (found_transid > fs_devices->latest_trans) { fs_devices->latest_devid = devid; fs_devices->latest_trans = found_transid; + } else if (found_transid < fs_devices->earliest_trans) { + fs_devices->earliest_devid = devid; + fs_devices->earliest_trans = found_transid; } - if (fs_devices->lowest_devid > devid) { + if (devid < fs_devices->lowest_devid) { fs_devices->lowest_devid = devid; } *fs_devices_ret = fs_devices; @@ -183,6 +188,8 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int flags) if (device->devid == fs_devices->latest_devid) fs_devices->latest_bdev = fd; + if (device->devid == fs_devices->earliest_devid) + fs_devices->earliest_bdev = fd; if (device->devid == fs_devices->lowest_devid) fs_devices->lowest_bdev = fd; device->fd = fd; diff --git a/volumes.h b/volumes.h index 7104d36..08c53e4 100644 --- a/volumes.h +++ b/volumes.h @@ -64,11 +64,15 @@ struct btrfs_device { struct btrfs_fs_devices { u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ - /* the device with this id has the most recent coyp of the super */ + /* the device with this id has the most recent copy of the super */ u64 latest_devid; u64 latest_trans; + /* the device with this id has the least recent copy of the super */ + u64 earliest_devid; + u64 earliest_trans; u64 lowest_devid; int latest_bdev; + int earliest_bdev; int lowest_bdev; struct list_head devices; struct list_head list; -- 1.7.6.233.gd79bc