summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Bentele2019-08-07 17:39:05 +0200
committerManuel Bentele2019-08-21 22:03:49 +0200
commit4a3ae0eee2cdef31c9548784adc439337d39e421 (patch)
tree928ead4faff8f19fd88ab63637bb6d44154cfe30
parentblock: loop: add debugfs support for loop devices (diff)
downloadkernel-qcow2-linux-4a3ae0eee2cdef31c9548784adc439337d39e421.tar.gz
kernel-qcow2-linux-4a3ae0eee2cdef31c9548784adc439337d39e421.tar.xz
kernel-qcow2-linux-4a3ae0eee2cdef31c9548784adc439337d39e421.zip
block: loop: file_fmt_qcow: increment read position for each bvec
The read position for a bvec was not incremented after the first reading of a bvec of a bio in a request. The reading only succeeds if the request consists only of one bio with corresponding bvec. This patch fixes this problem by incrementing the read position for each bvec after reading. Signed-off-by: Manuel Bentele <development@manuel-bentele.de>
-rw-r--r--drivers/block/loop/loop_file_fmt_qcow_main.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/block/loop/loop_file_fmt_qcow_main.c b/drivers/block/loop/loop_file_fmt_qcow_main.c
index 70436c8fc076..dc2a7b0ee287 100644
--- a/drivers/block/loop/loop_file_fmt_qcow_main.c
+++ b/drivers/block/loop/loop_file_fmt_qcow_main.c
@@ -781,14 +781,13 @@ out_free_in_buf:
static int __qcow_file_fmt_read_bvec(struct loop_file_fmt *lo_fmt,
struct bio_vec *bvec,
- loff_t pos)
+ loff_t *ppos)
{
struct loop_file_fmt_qcow_data *qcow_data = lo_fmt->private_data;
struct loop_device *lo = loop_file_fmt_get_lo(lo_fmt);
int offset_in_cluster;
int ret;
unsigned int cur_bytes; /* number of bytes in current iteration */
- u64 offset;
u64 bytes;
u64 cluster_offset = 0;
u64 bytes_done = 0;
@@ -797,22 +796,21 @@ static int __qcow_file_fmt_read_bvec(struct loop_file_fmt *lo_fmt,
ssize_t len;
loff_t pos_read;
- offset = pos;
bytes = bvec->bv_len;
- while (bytes > 0) {
+ while (bytes != 0) {
/* prepare next request */
cur_bytes = bytes;
- ret = loop_file_fmt_qcow_cluster_get_offset(lo_fmt, offset,
+ ret = loop_file_fmt_qcow_cluster_get_offset(lo_fmt, *ppos,
&cur_bytes, &cluster_offset);
if (ret < 0) {
goto fail;
}
offset_in_cluster = loop_file_fmt_qcow_offset_into_cluster(
- qcow_data, offset);
+ qcow_data, *ppos);
switch (ret) {
case QCOW_CLUSTER_UNALLOCATED:
@@ -826,7 +824,7 @@ static int __qcow_file_fmt_read_bvec(struct loop_file_fmt *lo_fmt,
case QCOW_CLUSTER_COMPRESSED:
ret = __qcow_file_fmt_read_compressed(lo_fmt, bvec,
- cluster_offset, offset, cur_bytes);
+ cluster_offset, *ppos, cur_bytes);
if (ret < 0) {
goto fail;
}
@@ -858,7 +856,7 @@ static int __qcow_file_fmt_read_bvec(struct loop_file_fmt *lo_fmt,
}
bytes -= cur_bytes;
- offset += cur_bytes;
+ *ppos += cur_bytes;
bytes_done += cur_bytes;
}
@@ -876,18 +874,10 @@ static int qcow_file_fmt_read(struct loop_file_fmt *lo_fmt,
loff_t pos;
int ret = 0;
- u64 cluster_offset;
- unsigned int cur_bytes = blk_rq_bytes(rq);
-
pos = __qcow_file_fmt_rq_get_pos(lo_fmt, rq);
- ret = loop_file_fmt_qcow_cluster_get_offset(lo_fmt, pos, &cur_bytes,
- &cluster_offset);
-
- ret = 0;
-
rq_for_each_segment(bvec, rq, iter) {
- ret = __qcow_file_fmt_read_bvec(lo_fmt, &bvec, pos);
+ ret = __qcow_file_fmt_read_bvec(lo_fmt, &bvec, &pos);
if (ret)
return ret;