diff options
author | Paul Durrant <paul.durrant@citrix.com> | 2019-04-09 17:40:38 +0100 |
---|---|---|
committer | Anthony PERARD <anthony.perard@citrix.com> | 2019-06-24 10:42:29 +0100 |
commit | 5feeb718d7914c3c921cc811a5844488a5644ea6 (patch) | |
tree | 89a3be3e12f0bcaec1f1a1b009ecf9e1937ed7ee /hw/block/dataplane | |
parent | 474f3938d79ab36b9231c9ad3b5a9314c2aeacde (diff) |
xen-block: support feature-large-sector-size
A recent Xen commit [1] clarified the semantics of sector based quantities
used in the blkif protocol such that it is now safe to create a xen-block
device with a logical_block_size != 512, as long as the device only
connects to a frontend advertizing 'feature-large-block-size'.
This patch modifies xen-block accordingly. It also uses a stack variable
for the BlockBackend in xen_block_realize() to avoid repeated dereferencing
of the BlockConf pointer, and changes the parameters of
xen_block_dataplane_create() so that the BlockBackend pointer and sector
size are passed expicitly rather than implicitly via the BlockConf.
These modifications have been tested against a recent Windows PV XENVBD
driver [2] using a xen-disk device with a 4kB logical block size.
[1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=67e1c050e36b2c9900cca83618e56189effbad98
[2] https://winpvdrvbuild.xenproject.org:8080/job/XENVBD-master/126
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Message-Id: <20190409164038.25484-1-paul.durrant@citrix.com>
[Edited error message]
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Diffstat (limited to 'hw/block/dataplane')
-rw-r--r-- | hw/block/dataplane/xen-block.c | 25 | ||||
-rw-r--r-- | hw/block/dataplane/xen-block.h | 3 |
2 files changed, 16 insertions, 12 deletions
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index f7ad452bbd..6da5c77fbb 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -58,6 +58,7 @@ struct XenBlockDataPlane { int requests_inflight; unsigned int max_requests; BlockBackend *blk; + unsigned int sector_size; QEMUBH *bh; IOThread *iothread; AioContext *ctx; @@ -167,7 +168,7 @@ static int xen_block_parse_request(XenBlockRequest *request) goto err; } - request->start = request->req.sector_number * XEN_BLKIF_SECTOR_SIZE; + request->start = request->req.sector_number * dataplane->sector_size; for (i = 0; i < request->req.nr_segments; i++) { if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) { error_report("error: nr_segments too big"); @@ -177,14 +178,14 @@ static int xen_block_parse_request(XenBlockRequest *request) error_report("error: first > last sector"); goto err; } - if (request->req.seg[i].last_sect * XEN_BLKIF_SECTOR_SIZE >= + if (request->req.seg[i].last_sect * dataplane->sector_size >= XC_PAGE_SIZE) { error_report("error: page crossing"); goto err; } len = (request->req.seg[i].last_sect - - request->req.seg[i].first_sect + 1) * XEN_BLKIF_SECTOR_SIZE; + request->req.seg[i].first_sect + 1) * dataplane->sector_size; request->size += len; } if (request->start + request->size > blk_getlength(dataplane->blk)) { @@ -218,17 +219,17 @@ static int xen_block_copy_request(XenBlockRequest *request) if (to_domain) { segs[i].dest.foreign.ref = request->req.seg[i].gref; segs[i].dest.foreign.offset = request->req.seg[i].first_sect * - XEN_BLKIF_SECTOR_SIZE; + dataplane->sector_size; segs[i].source.virt = virt; } else { segs[i].source.foreign.ref = request->req.seg[i].gref; segs[i].source.foreign.offset = request->req.seg[i].first_sect * - XEN_BLKIF_SECTOR_SIZE; + dataplane->sector_size; segs[i].dest.virt = virt; } segs[i].len = (request->req.seg[i].last_sect - request->req.seg[i].first_sect + 1) * - XEN_BLKIF_SECTOR_SIZE; + dataplane->sector_size; virt += segs[i].len; } @@ -336,12 +337,12 @@ static bool xen_block_split_discard(XenBlockRequest *request, /* Wrap around, or overflowing byte limit? */ if (sec_start + sec_count < sec_count || - sec_start + sec_count > INT64_MAX / XEN_BLKIF_SECTOR_SIZE) { + sec_start + sec_count > INT64_MAX / dataplane->sector_size) { return false; } - byte_offset = sec_start * XEN_BLKIF_SECTOR_SIZE; - byte_remaining = sec_count * XEN_BLKIF_SECTOR_SIZE; + byte_offset = sec_start * dataplane->sector_size; + byte_remaining = sec_count * dataplane->sector_size; do { byte_chunk = byte_remaining > BDRV_REQUEST_MAX_BYTES ? @@ -625,13 +626,15 @@ static void xen_block_dataplane_event(void *opaque) } XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, - BlockConf *conf, + BlockBackend *blk, + unsigned int sector_size, IOThread *iothread) { XenBlockDataPlane *dataplane = g_new0(XenBlockDataPlane, 1); dataplane->xendev = xendev; - dataplane->blk = conf->blk; + dataplane->blk = blk; + dataplane->sector_size = sector_size; QLIST_INIT(&dataplane->inflight); QLIST_INIT(&dataplane->freelist); diff --git a/hw/block/dataplane/xen-block.h b/hw/block/dataplane/xen-block.h index d6fa6d26dd..76dcd51c3d 100644 --- a/hw/block/dataplane/xen-block.h +++ b/hw/block/dataplane/xen-block.h @@ -15,7 +15,8 @@ typedef struct XenBlockDataPlane XenBlockDataPlane; XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, - BlockConf *conf, + BlockBackend *blk, + unsigned int sector_size, IOThread *iothread); void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane); void xen_block_dataplane_start(XenBlockDataPlane *dataplane, |