diff options
Diffstat (limited to 'extent_io.c')
-rw-r--r-- | extent_io.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/extent_io.c b/extent_io.c index 78deb502..5093aeb2 100644 --- a/extent_io.c +++ b/extent_io.c @@ -27,6 +27,8 @@ #include "kerncompat.h" #include "extent_io.h" #include "list.h" +#include "ctree.h" +#include "volumes.h" u64 cache_soft_max = 1024 * 1024 * 256; u64 cache_hard_max = 1 * 1024 * 1024 * 1024; @@ -696,6 +698,55 @@ out: return ret; } +int read_data_from_disk(struct btrfs_fs_info *info, void *buf, u64 offset, + u64 bytes, int mirror) +{ + struct btrfs_multi_bio *multi = NULL; + struct btrfs_device *device; + u64 bytes_left = bytes; + u64 read_len; + u64 total_read = 0; + int ret; + + while (bytes_left) { + read_len = bytes_left; + ret = btrfs_map_block(&info->mapping_tree, READ, offset, + &read_len, &multi, mirror, NULL); + if (ret) { + fprintf(stderr, "Couldn't map the block %Lu\n", + offset); + return -EIO; + } + device = multi->stripes[0].dev; + + read_len = min(bytes_left, read_len); + if (device->fd == 0) { + kfree(multi); + return -EIO; + } + + ret = pread(device->fd, buf + total_read, read_len, + multi->stripes[0].physical); + kfree(multi); + if (ret < 0) { + fprintf(stderr, "Error reading %Lu, %d\n", offset, + ret); + return ret; + } + if (ret != read_len) { + fprintf(stderr, "Short read for %Lu, read %d, " + "read_len %Lu\n", offset, ret, read_len); + return -EIO; + } + + bytes_left -= read_len; + offset += read_len; + total_read += read_len; + } + + return 0; +} + int set_extent_buffer_uptodate(struct extent_buffer *eb) { eb->flags |= EXTENT_UPTODATE; |