aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/disk-io.c49
-rw-r--r--fs/squashfs/sqfs.c16
2 files changed, 38 insertions, 27 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3f0d9f1c11..7eaa7e9496 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -541,34 +541,39 @@ struct extent_buffer* read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
int read_extent_data(struct btrfs_fs_info *fs_info, char *data, u64 logical,
u64 *len, int mirror)
{
- u64 offset = 0;
+ u64 orig_len = *len;
+ u64 cur = logical;
struct btrfs_multi_bio *multi = NULL;
struct btrfs_device *device;
int ret = 0;
- u64 max_len = *len;
- ret = btrfs_map_block(fs_info, READ, logical, len, &multi, mirror,
- NULL);
- if (ret) {
- fprintf(stderr, "Couldn't map the block %llu\n",
- logical + offset);
- goto err;
- }
- device = multi->stripes[0].dev;
-
- if (*len > max_len)
- *len = max_len;
- if (!device->desc || !device->part) {
- ret = -EIO;
- goto err;
- }
+ while (cur < logical + orig_len) {
+ u64 cur_len = logical + orig_len - cur;
- ret = __btrfs_devread(device->desc, device->part, data, *len,
- multi->stripes[0].physical);
- if (ret != *len)
- ret = -EIO;
- else
+ ret = btrfs_map_block(fs_info, READ, cur, &cur_len, &multi,
+ mirror, NULL);
+ if (ret) {
+ error("Couldn't map the block %llu", cur);
+ goto err;
+ }
+ device = multi->stripes[0].dev;
+ if (!device->desc || !device->part) {
+ error("devid %llu is missing", device->devid);
+ ret = -EIO;
+ goto err;
+ }
+ ret = __btrfs_devread(device->desc, device->part,
+ data + (cur - logical), cur_len,
+ multi->stripes[0].physical);
+ if (ret != cur_len) {
+ error("read failed on devid %llu physical %llu",
+ device->devid, multi->stripes[0].physical);
+ ret = -EIO;
+ goto err;
+ }
+ cur += cur_len;
ret = 0;
+ }
err:
kfree(multi);
return ret;
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 4226621923..1430e671a5 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -100,7 +100,7 @@ static int sqfs_calc_n_blks(__le64 start, __le64 end, u64 *offset)
static int sqfs_frag_lookup(u32 inode_fragment_index,
struct squashfs_fragment_block_entry *e)
{
- u64 start, n_blks, src_len, table_offset, start_block;
+ u64 start, end, exp_tbl, n_blks, src_len, table_offset, start_block;
unsigned char *metadata_buffer, *metadata, *table;
struct squashfs_fragment_block_entry *entries;
struct squashfs_super_block *sblk = ctxt.sblk;
@@ -115,11 +115,17 @@ static int sqfs_frag_lookup(u32 inode_fragment_index,
if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments))
return -EINVAL;
- start = get_unaligned_le64(&sblk->fragment_table_start) /
- ctxt.cur_dev->blksz;
+ start = get_unaligned_le64(&sblk->fragment_table_start);
+ end = get_unaligned_le64(&sblk->id_table_start);
+ exp_tbl = get_unaligned_le64(&sblk->export_table_start);
+
+ if (exp_tbl > start && exp_tbl < end)
+ end = exp_tbl;
+
n_blks = sqfs_calc_n_blks(sblk->fragment_table_start,
- sblk->export_table_start,
- &table_offset);
+ cpu_to_le64(end), &table_offset);
+
+ start /= ctxt.cur_dev->blksz;
/* Allocate a proper sized buffer to store the fragment index table */
table = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);