summaryrefslogtreecommitdiff
path: root/btrfs-image.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2015-08-21 11:21:27 +0800
committerDavid Sterba <dsterba@suse.com>2015-08-31 19:25:13 +0200
commit2d46558b30f5e130085212de7e3a22e2780e8d2a (patch)
tree36d3b8de60bde2b8f9f29615df193292f801026c /btrfs-image.c
parent59df5b6e9aacd222b79f27886b6989bff3eef2a9 (diff)
downloadbtrfs-progs-2d46558b30f5e130085212de7e3a22e2780e8d2a.tar.gz
btrfs-progs: Use existing facility to replace read_data_extent function
Function read_data_extent() in btrfs-image.c is using manual-and-read codes. Replace it with existing read_extent_data() to reduce duplication. Also, now we can use other mirror to try our best to do the dump, just like read_tree_block(). Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'btrfs-image.c')
-rw-r--r--btrfs-image.c58
1 files changed, 19 insertions, 39 deletions
diff --git a/btrfs-image.c b/btrfs-image.c
index b225325..f48d81a 100644
--- a/btrfs-image.c
+++ b/btrfs-image.c
@@ -872,54 +872,34 @@ out:
static int read_data_extent(struct metadump_struct *md,
struct async_work *async)
{
- struct btrfs_multi_bio *multi = NULL;
- struct btrfs_device *device;
+ struct btrfs_root *root = md->root;
u64 bytes_left = async->size;
u64 logical = async->start;
u64 offset = 0;
- u64 bytenr;
u64 read_len;
- ssize_t done;
- int fd;
+ int num_copies;
+ int cur_mirror;
int ret;
- while (bytes_left) {
- read_len = bytes_left;
- ret = btrfs_map_block(&md->root->fs_info->mapping_tree, READ,
- logical, &read_len, &multi, 0, NULL);
- if (ret) {
- fprintf(stderr, "Couldn't map data block %d\n", ret);
- return ret;
- }
-
- device = multi->stripes[0].dev;
-
- if (device->fd <= 0) {
- fprintf(stderr,
- "Device we need to read from is not open\n");
- free(multi);
- return -EIO;
- }
- fd = device->fd;
- bytenr = multi->stripes[0].physical;
- free(multi);
+ num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, logical,
+ bytes_left);
- read_len = min(read_len, bytes_left);
- done = pread64(fd, async->buffer+offset, read_len, bytenr);
- if (done < read_len) {
- if (done < 0)
- fprintf(stderr, "Error reading extent %d\n",
- errno);
- else
- fprintf(stderr, "Short read\n");
- return -EIO;
+ /* Try our best to read data, just like read_tree_block() */
+ for (cur_mirror = 0; cur_mirror < num_copies; cur_mirror++) {
+ while (bytes_left) {
+ read_len = bytes_left;
+ ret = read_extent_data(root,
+ (char *)(async->buffer + offset),
+ logical, &read_len, cur_mirror);
+ if (ret < 0)
+ break;
+ offset += read_len;
+ logical += read_len;
+ bytes_left -= read_len;
}
-
- bytes_left -= done;
- offset += done;
- logical += done;
}
-
+ if (bytes_left)
+ return -EIO;
return 0;
}