diff options
-rw-r--r-- | btrfs-image.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/btrfs-image.c b/btrfs-image.c index f6347f36..4bcaf6c2 100644 --- a/btrfs-image.c +++ b/btrfs-image.c @@ -868,6 +868,15 @@ static int read_data_extent(struct metadump_struct *md, return 0; } +static int get_dev_fd(struct btrfs_root *root) +{ + struct btrfs_device *dev; + + dev = list_first_entry(&root->fs_info->fs_devices->devices, + struct btrfs_device, dev_list); + return dev->fd; +} + static int flush_pending(struct metadump_struct *md, int done) { struct async_work *async = NULL; @@ -904,6 +913,24 @@ static int flush_pending(struct metadump_struct *md, int done) } } + /* + * Balance can make the mapping not cover the super block, so + * just copy directly from one of the devices. + */ + if (start == BTRFS_SUPER_INFO_OFFSET) { + int fd = get_dev_fd(md->root); + + ret = pread64(fd, async->buffer, size, start); + if (ret < size) { + free(async->buffer); + free(async); + fprintf(stderr, "Error reading superblock\n"); + return -EIO; + } + size = 0; + ret = 0; + } + while (!md->data && size > 0) { u64 this_read = min(blocksize, size); eb = read_tree_block(md->root, start, this_read, 0); |