summaryrefslogtreecommitdiff
path: root/extent_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'extent_io.c')
-rw-r--r--extent_io.c51
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;