Skip to content

Commit a984a2e

Browse files
committed
CP-37221: Only read data where present in bitmap
Reading an entire 2MB allocation block from the node being coalesced when only a small portion of it is required incurs a significant performance overhead and makes it hard for the coalesce process to complete if there is any significant amount of IO occuring in the guest. Update vhd_util_coaleasce_block to read only those extents marked as present in the bitmap when the BATMAP is not stuffed. Signed-off-by: Mark Syms <[email protected]>
1 parent 6a8bcf6 commit a984a2e

File tree

3 files changed

+50
-22
lines changed

3 files changed

+50
-22
lines changed

include/libvhd.h

+1
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ int vhd_read_header_at(vhd_context_t *, vhd_header_t *, off64_t);
351351
int vhd_read_bat(vhd_context_t *, vhd_bat_t *);
352352
int vhd_read_batmap(vhd_context_t *, vhd_batmap_t *);
353353
int vhd_read_bitmap(vhd_context_t *, uint32_t block, char **bufp);
354+
int vhd_read_at(vhd_context_t *ctx, uint64_t block, uint32_t from, size_t size, char *buf);
354355
int vhd_read_block(vhd_context_t *, uint32_t block, char **bufp);
355356

356357
int vhd_write_footer(vhd_context_t *, vhd_footer_t *);

vhd/lib/libvhd.c

+34-18
Original file line numberDiff line numberDiff line change
@@ -2041,20 +2041,15 @@ vhd_read_bitmap(vhd_context_t *ctx, uint32_t block, char **bufp)
20412041
}
20422042

20432043
int
2044-
vhd_read_block(vhd_context_t *ctx, uint32_t block, char **bufp)
2044+
vhd_read_at(vhd_context_t *ctx, uint64_t block, uint32_t from, size_t size, char *buf)
20452045
{
2046+
/*
2047+
* Sub call function, assumes that dynamic disk has been checked
2048+
*/
20462049
int err;
2047-
void *buf;
2048-
size_t size;
20492050
uint64_t blk;
20502051
off64_t end, off;
20512052

2052-
buf = NULL;
2053-
*bufp = NULL;
2054-
2055-
if (!vhd_type_dynamic(ctx))
2056-
return -EINVAL;
2057-
20582053
err = vhd_get_bat(ctx);
20592054
if (err)
20602055
return err;
@@ -2067,34 +2062,55 @@ vhd_read_block(vhd_context_t *ctx, uint32_t block, char **bufp)
20672062
return -EINVAL;
20682063

20692064
off = vhd_sectors_to_bytes(blk + ctx->bm_secs);
2070-
size = vhd_sectors_to_bytes(ctx->spb);
20712065

20722066
err = vhd_footer_offset_at_eof(ctx, &end);
20732067
if (err)
20742068
return err;
20752069

2076-
err = posix_memalign(&buf, VHD_SECTOR_SIZE, size);
2077-
if (err) {
2078-
err = -err;
2079-
goto fail;
2080-
}
2081-
20822070
if (end < off + ctx->header.block_size) {
20832071
size = end - off;
20842072
memset(buf + size, 0, ctx->header.block_size - size);
20852073
}
20862074

2075+
off = off + vhd_sectors_to_bytes(from);
2076+
20872077
err = vhd_seek(ctx, off, SEEK_SET);
20882078
if (err)
2089-
goto fail;
2079+
return err;
20902080

20912081
err = vhd_read(ctx, buf, size);
2082+
if (err)
2083+
return err;
2084+
2085+
return 0;
2086+
}
2087+
2088+
int
2089+
vhd_read_block(vhd_context_t *ctx, uint32_t block, char **bufp)
2090+
{
2091+
int err;
2092+
void *buf;
2093+
size_t size;
2094+
2095+
buf = NULL;
2096+
*bufp = NULL;
2097+
2098+
if (!vhd_type_dynamic(ctx))
2099+
return -EINVAL;
2100+
2101+
size = vhd_sectors_to_bytes(ctx->spb);
2102+
err = posix_memalign(&buf, VHD_SECTOR_SIZE, size);
2103+
if (err) {
2104+
err = -err;
2105+
goto fail;
2106+
}
2107+
2108+
err = vhd_read_at(ctx, block, 0, size, buf);
20922109
if (err)
20932110
goto fail;
20942111

20952112
*bufp = buf;
20962113
return 0;
2097-
20982114
fail:
20992115
free(buf);
21002116
return err;

vhd/lib/vhd-util-coalesce.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ vhd_util_coalesce_block(vhd_context_t *vhd, vhd_context_t *parent,
8484
if (vhd->bat.bat[block] == DD_BLK_UNUSED)
8585
return 0;
8686

87-
err = vhd_read_block(vhd, block, &buf);
88-
if (err)
89-
goto done;
90-
9187
if (vhd_has_batmap(vhd) && vhd_batmap_test(vhd, &vhd->batmap, block)) {
88+
err = vhd_read_block(vhd, block, &buf);
89+
if (err)
90+
goto done;
91+
9292
if (parent->file)
9393
err = vhd_io_write(parent, buf, sec, vhd->spb);
9494
else
@@ -100,6 +100,12 @@ vhd_util_coalesce_block(vhd_context_t *vhd, vhd_context_t *parent,
100100
if (err)
101101
goto done;
102102

103+
err = posix_memalign((void *)&buf, 4096, vhd->header.block_size);
104+
if (err) {
105+
err = -err;
106+
goto done;
107+
}
108+
103109
for (i = 0; i < vhd->spb; i++) {
104110
if (!vhd_bitmap_test(vhd, map, i))
105111
continue;
@@ -108,6 +114,11 @@ vhd_util_coalesce_block(vhd_context_t *vhd, vhd_context_t *parent,
108114
if (!vhd_bitmap_test(vhd, map, i + secs))
109115
break;
110116

117+
err = vhd_read_at(vhd, block, i, vhd_sectors_to_bytes(secs),
118+
buf + vhd_sectors_to_bytes(i));
119+
if (err)
120+
goto done;
121+
111122
if (parent->file)
112123
err = vhd_io_write(parent,
113124
buf + vhd_sectors_to_bytes(i),

0 commit comments

Comments
 (0)