Skip to content

Commit

Permalink
block: Convert bdrv_co_discard() to byte-based
Browse files Browse the repository at this point in the history
Another step towards byte-based interfaces everywhere.  Replace
the sector-based bdrv_co_discard() with a new byte-based
bdrv_co_pdiscard(), which silently ignores any unaligned head
or tail.  Driver callbacks will be converted in followup patches.

By calculating the alignment outside of the loop, and clamping
the max discard to an aligned value, we can simplify the actions
done within the loop.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1468624988-423-2-git-send-email-eblake@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
ebblake authored and stefanhaRH committed Jul 20, 2016
1 parent 6bd01f1 commit 9f1963b
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 36 deletions.
3 changes: 2 additions & 1 deletion block/blkreplay.c
Expand Up @@ -118,7 +118,8 @@ static int coroutine_fn blkreplay_co_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors)
{
uint64_t reqid = request_id++;
int ret = bdrv_co_discard(bs->file->bs, sector_num, nb_sectors);
int ret = bdrv_co_pdiscard(bs->file->bs, sector_num << BDRV_SECTOR_BITS,
nb_sectors << BDRV_SECTOR_BITS);
block_request_create(reqid, bs, qemu_coroutine_self());
qemu_coroutine_yield();

Expand Down
3 changes: 2 additions & 1 deletion block/block-backend.c
Expand Up @@ -1113,7 +1113,8 @@ int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
return ret;
}

return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors);
return bdrv_co_pdiscard(blk_bs(blk), sector_num << BDRV_SECTOR_BITS,
nb_sectors << BDRV_SECTOR_BITS);
}

int blk_co_flush(BlockBackend *blk)
Expand Down
67 changes: 35 additions & 32 deletions block/io.c
Expand Up @@ -2199,7 +2199,8 @@ static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
BlockAIOCBCoroutine *acb = opaque;
BlockDriverState *bs = acb->common.bs;

acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
acb->req.error = bdrv_co_pdiscard(bs, acb->req.sector << BDRV_SECTOR_BITS,
acb->req.nb_sectors << BDRV_SECTOR_BITS);
bdrv_co_complete(acb);
}

Expand Down Expand Up @@ -2398,20 +2399,22 @@ static void coroutine_fn bdrv_discard_co_entry(void *opaque)
{
DiscardCo *rwco = opaque;

rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
rwco->ret = bdrv_co_pdiscard(rwco->bs, rwco->sector_num << BDRV_SECTOR_BITS,
rwco->nb_sectors << BDRV_SECTOR_BITS);
}

int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
int count)
{
BdrvTrackedRequest req;
int max_discard, ret;
int max_pdiscard, ret;
int head, align;

if (!bs->drv) {
return -ENOMEDIUM;
}

ret = bdrv_check_request(bs, sector_num, nb_sectors);
ret = bdrv_check_byte_request(bs, offset, count);
if (ret < 0) {
return ret;
} else if (bs->read_only) {
Expand All @@ -2428,45 +2431,45 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
return 0;
}

tracked_request_begin(&req, bs, sector_num << BDRV_SECTOR_BITS,
nb_sectors << BDRV_SECTOR_BITS, BDRV_TRACKED_DISCARD);
/* Discard is advisory, so ignore any unaligned head or tail */
align = MAX(BDRV_SECTOR_SIZE,
MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment));
assert(is_power_of_2(align));
head = MIN(count, -offset & (align - 1));
if (head) {
count -= head;
offset += head;
}
count = QEMU_ALIGN_DOWN(count, align);
if (!count) {
return 0;
}

tracked_request_begin(&req, bs, offset, count, BDRV_TRACKED_DISCARD);

ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req);
if (ret < 0) {
goto out;
}

max_discard = MIN_NON_ZERO(bs->bl.max_pdiscard >> BDRV_SECTOR_BITS,
BDRV_REQUEST_MAX_SECTORS);
while (nb_sectors > 0) {
int ret;
int num = nb_sectors;
int discard_alignment = bs->bl.pdiscard_alignment >> BDRV_SECTOR_BITS;

/* align request */
if (discard_alignment &&
num >= discard_alignment &&
sector_num % discard_alignment) {
if (num > discard_alignment) {
num = discard_alignment;
}
num -= sector_num % discard_alignment;
}
max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX),
align);

/* limit request size */
if (num > max_discard) {
num = max_discard;
}
while (count > 0) {
int ret;
int num = MIN(count, max_pdiscard);

if (bs->drv->bdrv_co_discard) {
ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
ret = bs->drv->bdrv_co_discard(bs, offset >> BDRV_SECTOR_BITS,
num >> BDRV_SECTOR_BITS);
} else {
BlockAIOCB *acb;
CoroutineIOCompletion co = {
.coroutine = qemu_coroutine_self(),
};

acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
acb = bs->drv->bdrv_aio_discard(bs, offset >> BDRV_SECTOR_BITS,
num >> BDRV_SECTOR_BITS,
bdrv_co_io_em_complete, &co);
if (acb == NULL) {
ret = -EIO;
Expand All @@ -2480,8 +2483,8 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
goto out;
}

sector_num += num;
nb_sectors -= num;
offset += num;
count -= num;
}
ret = 0;
out:
Expand Down
3 changes: 2 additions & 1 deletion block/raw_bsd.c
Expand Up @@ -137,7 +137,8 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
static int coroutine_fn raw_co_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors)
{
return bdrv_co_discard(bs->file->bs, sector_num, nb_sectors);
return bdrv_co_pdiscard(bs->file->bs, sector_num << BDRV_SECTOR_BITS,
nb_sectors << BDRV_SECTOR_BITS);
}

static int64_t raw_getlength(BlockDriverState *bs)
Expand Down
2 changes: 1 addition & 1 deletion include/block/block.h
Expand Up @@ -342,7 +342,7 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
void bdrv_drain_all(void);

int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int count);
int bdrv_has_zero_init_1(BlockDriverState *bs);
int bdrv_has_zero_init(BlockDriverState *bs);
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
Expand Down

0 comments on commit 9f1963b

Please sign in to comment.