Skip to content

Commit

Permalink
parallels: naive implementation of allocate_clusters with used bitmap
Browse files Browse the repository at this point in the history
The access to the bitmap is not optimized completely.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
  • Loading branch information
Denis V. Lunev committed Sep 21, 2023
1 parent eeb1e6d commit 3ac10d1
Showing 1 changed file with 39 additions and 12 deletions.
51 changes: 39 additions & 12 deletions block/parallels.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
{
int ret = 0;
BDRVParallelsState *s = bs->opaque;
int64_t pos, space, idx, to_allocate, i, len;
int64_t i, pos, idx, to_allocate, first_free, host_off;

pos = block_status(s, sector_num, nb_sectors, pnum);
if (pos > 0) {
Expand All @@ -276,15 +276,13 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
*/
assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);

space = to_allocate * s->tracks;
len = bdrv_co_getlength(bs->file->bs);
if (len < 0) {
return len;
}
if (s->data_end + space > (len >> BDRV_SECTOR_BITS)) {
first_free = find_first_zero_bit(s->used_bmap, s->used_bmap_size);
if (first_free == s->used_bmap_size) {
uint32_t new_usedsize;
int64_t space = to_allocate * s->tracks + s->prealloc_size;

host_off = s->data_end * BDRV_SECTOR_SIZE;

space += s->prealloc_size;
/*
* We require the expanded size to read back as zero. If the
* user permitted truncation, we try that; but if it fails, we
Expand Down Expand Up @@ -313,6 +311,32 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
s->used_bmap = bitmap_zero_extend(s->used_bmap, s->used_bmap_size,
new_usedsize);
s->used_bmap_size = new_usedsize;
} else {
int64_t next_used;
next_used = find_next_bit(s->used_bmap, s->used_bmap_size, first_free);

/* Not enough continuous clusters in the middle, adjust the size */
if (next_used - first_free < to_allocate) {
to_allocate = next_used - first_free;
*pnum = (idx + to_allocate) * s->tracks - sector_num;
}

host_off = s->data_start * BDRV_SECTOR_SIZE;
host_off += first_free * s->cluster_size;

/*
* No need to preallocate if we are using tail area from the above
* branch. In the other case we are likely re-using hole. Preallocate
* the space if required by the prealloc_mode.
*/
if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE &&
host_off < s->data_end * BDRV_SECTOR_SIZE) {
ret = bdrv_co_pwrite_zeroes(bs->file, host_off,
s->cluster_size * to_allocate, 0);
if (ret < 0) {
return ret;
}
}
}

/*
Expand Down Expand Up @@ -344,15 +368,18 @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
}
}

ret = mark_used(bs, s->used_bmap, s->used_bmap_size,
s->data_end << BDRV_SECTOR_BITS, to_allocate);
ret = mark_used(bs, s->used_bmap, s->used_bmap_size, host_off, to_allocate);
if (ret < 0) {
/* Image consistency is broken. Alarm! */
return ret;
}
for (i = 0; i < to_allocate; i++) {
parallels_set_bat_entry(s, idx + i, s->data_end / s->off_multiplier);
s->data_end += s->tracks;
parallels_set_bat_entry(s, idx + i,
host_off / BDRV_SECTOR_SIZE / s->off_multiplier);
host_off += s->cluster_size;
}
if (host_off > s->data_end * BDRV_SECTOR_SIZE) {
s->data_end = host_off / BDRV_SECTOR_SIZE;
}

return bat2sect(s, idx) + sector_num % s->tracks;
Expand Down

0 comments on commit 3ac10d1

Please sign in to comment.