diff options
author | Peter Lieven <pl@kamp.de> | 2016-07-18 10:52:19 +0200 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2016-08-05 16:03:41 -0500 |
commit | 5634eb8ffb935045a6dd7e517eec5b838b6bc3e6 (patch) | |
tree | 9c6401e41a147db4f54fe2c10f15581d3804a240 /block | |
parent | b6ece2c6f37926a994bc564a9e55ef3be6016d8f (diff) |
block/iscsi: fix rounding in iscsi_allocationmap_set
when setting clusters as alloacted the boundaries have
to be expanded. As Paolo pointed out the calculation of
the number of clusters is wrong:
Suppose cluster_sectors is 2, sector_num = 1, nb_sectors = 6:
In the "mark allocated" case, you want to set 0..8, i.e.
cluster_num=0, nb_clusters=4.
0--.--2--.--4--.--6--.--8
<--|_________________|--> (<--> = expanded)
Instead you are setting nb_clusters=3, so that 6..8 is not marked.
0--.--2--.--4--.--6--.--8
<--|______________|!!! (! = wrong)
Cc: qemu-stable@nongnu.org
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1468831940-15556-2-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit eb36b953e0ebf4129b188a241fbc367062ac2e06)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/iscsi.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/block/iscsi.c b/block/iscsi.c index 172e6cfcc3..0466c30fda 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -425,12 +425,14 @@ static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun) static void iscsi_allocationmap_set(IscsiLun *iscsilun, int64_t sector_num, int nb_sectors) { + int64_t cluster_num, nb_clusters; if (iscsilun->allocationmap == NULL) { return; } - bitmap_set(iscsilun->allocationmap, - sector_num / iscsilun->cluster_sectors, - DIV_ROUND_UP(nb_sectors, iscsilun->cluster_sectors)); + cluster_num = sector_num / iscsilun->cluster_sectors; + nb_clusters = DIV_ROUND_UP(sector_num + nb_sectors, + iscsilun->cluster_sectors) - cluster_num; + bitmap_set(iscsilun->allocationmap, cluster_num, nb_clusters); } static void iscsi_allocationmap_clear(IscsiLun *iscsilun, int64_t sector_num, |