[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 19/24] block: Extract common write req handling
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 19/24] block: Extract common write req handling |
Date: |
Tue, 10 Jul 2018 17:42:59 +0200 |
From: Fam Zheng <address@hidden>
As a mechanical refactoring patch, this is the first step towards
unified and more correct write code paths. This is helpful because
multiple BlockDriverState fields need to be updated after modifying
image data, and it's hard to maintain in multiple places such as copy
offload, discard and truncate.
Suggested-by: Kevin Wolf <address@hidden>
Signed-off-by: Fam Zheng <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/io.c | 91 +++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 57 insertions(+), 34 deletions(-)
diff --git a/block/io.c b/block/io.c
index 6293612e73..313fe0776c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1575,6 +1575,61 @@ fail:
return ret;
}
+static inline int coroutine_fn
+bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
+ BdrvTrackedRequest *req, int flags)
+{
+ BlockDriverState *bs = child->bs;
+ bool waited;
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
+
+ if (bs->read_only) {
+ return -EPERM;
+ }
+
+ /* BDRV_REQ_NO_SERIALISING is only for read operation */
+ assert(!(flags & BDRV_REQ_NO_SERIALISING));
+ assert(!(bs->open_flags & BDRV_O_INACTIVE));
+ assert((bs->open_flags & BDRV_O_NO_IO) == 0);
+ assert(!(flags & ~BDRV_REQ_MASK));
+
+ if (flags & BDRV_REQ_SERIALISING) {
+ mark_request_serialising(req, bdrv_get_cluster_size(bs));
+ }
+
+ waited = wait_serialising_requests(req);
+
+ assert(!waited || !req->serialising ||
+ is_request_serialising_and_aligned(req));
+ assert(req->overlap_offset <= offset);
+ assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
+
+ if (flags & BDRV_REQ_WRITE_UNCHANGED) {
+ assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
+ } else {
+ assert(child->perm & BLK_PERM_WRITE);
+ }
+ assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
+ return notifier_with_return_list_notify(&bs->before_write_notifiers, req);
+}
+
+static inline void coroutine_fn
+bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, uint64_t bytes,
+ BdrvTrackedRequest *req, int ret)
+{
+ int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
+ BlockDriverState *bs = child->bs;
+
+ atomic_inc(&bs->write_gen);
+ bdrv_set_dirty(bs, offset, bytes);
+
+ stat64_max(&bs->wr_highest_offset, offset + bytes);
+
+ if (ret == 0) {
+ bs->total_sectors = MAX(bs->total_sectors, end_sector);
+ }
+}
+
/*
* Forwards an already correctly aligned write request to the BlockDriver,
* after possibly fragmenting it.
@@ -1585,10 +1640,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild
*child,
{
BlockDriverState *bs = child->bs;
BlockDriver *drv = bs->drv;
- bool waited;
int ret;
- int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
uint64_t bytes_remaining = bytes;
int max_transfer;
@@ -1604,31 +1657,10 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild
*child,
assert((offset & (align - 1)) == 0);
assert((bytes & (align - 1)) == 0);
assert(!qiov || bytes == qiov->size);
- assert((bs->open_flags & BDRV_O_NO_IO) == 0);
- assert(!(flags & ~BDRV_REQ_MASK));
max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX),
align);
- /* BDRV_REQ_NO_SERIALISING is only for read operation */
- assert(!(flags & BDRV_REQ_NO_SERIALISING));
-
- if (flags & BDRV_REQ_SERIALISING) {
- mark_request_serialising(req, bdrv_get_cluster_size(bs));
- }
-
- waited = wait_serialising_requests(req);
- assert(!waited || !req->serialising ||
- is_request_serialising_and_aligned(req));
- assert(req->overlap_offset <= offset);
- assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
- if (flags & BDRV_REQ_WRITE_UNCHANGED) {
- assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
- } else {
- assert(child->perm & BLK_PERM_WRITE);
- }
- assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
-
- ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
+ ret = bdrv_co_write_req_prepare(child, offset, bytes, req, flags);
if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF &&
!(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes &&
@@ -1677,15 +1709,10 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild
*child,
}
bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
- atomic_inc(&bs->write_gen);
- bdrv_set_dirty(bs, offset, bytes);
-
- stat64_max(&bs->wr_highest_offset, offset + bytes);
-
if (ret >= 0) {
- bs->total_sectors = MAX(bs->total_sectors, end_sector);
ret = 0;
}
+ bdrv_co_write_req_finish(child, offset, bytes, req, ret);
return ret;
}
@@ -1800,10 +1827,6 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
if (!bs->drv) {
return -ENOMEDIUM;
}
- if (bs->read_only) {
- return -EPERM;
- }
- assert(!(bs->open_flags & BDRV_O_INACTIVE));
ret = bdrv_check_byte_request(bs, offset, bytes);
if (ret < 0) {
--
2.13.6
- [Qemu-block] [PULL 10/24] block/blklogwrites: Make sure the log sector size is not too small, (continued)
- [Qemu-block] [PULL 10/24] block/blklogwrites: Make sure the log sector size is not too small, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 13/24] Revert "block: Remove deprecated -drive option addr", Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 15/24] block: Prefix file driver trace points with "file_", Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 12/24] Revert "block: Remove deprecated -drive option serial", Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 14/24] Revert "block: Remove deprecated -drive geometry options", Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 16/24] block: Add copy offloading trace points, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 17/24] block: Use BdrvChild to discard, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 18/24] block: Use uint64_t for BdrvTrackedRequest byte fields, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 22/24] block: Use common req handling in copy offloading, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 21/24] block: Use common req handling for discard, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 19/24] block: Extract common write req handling,
Kevin Wolf <=
- [Qemu-block] [PULL 20/24] block: Fix handling of image enlarging write, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 23/24] block: Fix bdrv_co_truncate overlap check, Kevin Wolf, 2018/07/10
- [Qemu-block] [PULL 24/24] block: Use common write req handling in truncate, Kevin Wolf, 2018/07/10
- Re: [Qemu-block] [PULL 00/24] Block layer patches, Peter Maydell, 2018/07/10