Skip to content

Commit

Permalink
Btrfs-progs: try other mirrors if decompression fails
Browse files Browse the repository at this point in the history
This will make the restore program fall back on other mirrors if it fails to
decompress an extent for whatever reason.  Thanks,

Signed-off-by: Josef Bacik <[email protected]>
  • Loading branch information
Josef Bacik authored and kdave committed Mar 18, 2013
1 parent 331295d commit 9969ea4
Showing 1 changed file with 25 additions and 21 deletions.
46 changes: 25 additions & 21 deletions cmds-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static int decompress(char *inbuf, char *outbuf, u64 compress_len,
ret = inflate(&strm, Z_NO_FLUSH);
if (ret != Z_STREAM_END) {
(void)inflateEnd(&strm);
fprintf(stderr, "ret is %d\n", ret);
fprintf(stderr, "failed to inflate: %d\n", ret);
return -1;
}

Expand Down Expand Up @@ -198,6 +198,8 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
int compress;
int ret;
int dev_fd;
int mirror_num = 0;
int num_copies;

compress = btrfs_file_extent_compression(leaf, fi);
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
Expand Down Expand Up @@ -226,12 +228,10 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
again:
length = size_left;
ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
bytenr, &length, &multi, 0, NULL);
bytenr, &length, &multi, mirror_num, NULL);
if (ret) {
free(inbuf);
free(outbuf);
fprintf(stderr, "Error mapping block %d\n", ret);
return ret;
goto out;
}
device = multi->stripes[0].dev;
dev_fd = device->fd;
Expand All @@ -245,52 +245,56 @@ static int copy_one_extent(struct btrfs_root *root, int fd,

done = pread(dev_fd, inbuf+count, length, dev_bytenr);
if (done < length) {
free(inbuf);
free(outbuf);
ret = -1;
fprintf(stderr, "Short read %d\n", errno);
return -1;
goto out;
}

count += length;
bytenr += length;
if (size_left)
goto again;


if (compress == BTRFS_COMPRESS_NONE) {
while (total < ram_size) {
done = pwrite(fd, inbuf+total, ram_size-total,
pos+total);
if (done < 0) {
free(inbuf);
ret = -1;
fprintf(stderr, "Error writing: %d %s\n", errno, strerror(errno));
return -1;
goto out;
}
total += done;
}
free(inbuf);
return 0;
ret = 0;
goto out;
}

ret = decompress(inbuf, outbuf, disk_size, ram_size);
free(inbuf);
if (ret) {
free(outbuf);
return ret;
num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
bytenr, length);
mirror_num++;
if (mirror_num >= num_copies) {
ret = -1;
goto out;
}
fprintf(stderr, "Trying another mirror\n");
goto again;
}

while (total < ram_size) {
done = pwrite(fd, outbuf+total, ram_size-total, pos+total);
if (done < 0) {
free(outbuf);
fprintf(stderr, "Error writing: %d %s\n", errno, strerror(errno));
return -1;
ret = -1;
goto out;
}
total += done;
}
out:
free(inbuf);
free(outbuf);

return 0;
return ret;
}

static int ask_to_continue(const char *file)
Expand Down

0 comments on commit 9969ea4

Please sign in to comment.