Skip to content

Commit 5564f06

Browse files
committed
Merge remote-tracking branch 'remotes/kwolf/tags/for-upstream' into staging
Block layer patches - Fix I/O errors because of incorrectly detected max_iov - Fix not white-listed copy-before-write - qemu-storage-daemon: Only display FUSE help when FUSE is built-in - iotests: update environment and linting configuration # gpg: Signature made Wed 06 Oct 2021 03:58:10 AM PDT # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "[email protected]" # gpg: Good signature from "Kevin Wolf <[email protected]>" [full] * remotes/kwolf/tags/for-upstream: iotests: Update for pylint 2.11.1 iotests/migrate-bitmaps-test: delint iotests/mirror-top-perms: Adjust imports iotests/linters: check mypy files all at once iotests: add 'qemu' package location to PYTHONPATH in testenv block: introduce max_hw_iov for use in scsi-generic iotests/image-fleecing: declare requirement of copy-before-write block: bdrv_insert_node(): don't use bdrv_open() block: bdrv_insert_node(): doc and style block: bdrv_insert_node(): fix and improve error handling block: implement bdrv_new_open_driver_opts() qemu-storage-daemon: Only display FUSE help when FUSE is built-in include/block.h: remove outdated comment Signed-off-by: Richard Henderson <[email protected]>
2 parents e3acc2c + 3765315 commit 5564f06

File tree

19 files changed

+164
-96
lines changed

19 files changed

+164
-96
lines changed

block.c

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,16 +1604,26 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
16041604
return ret;
16051605
}
16061606

1607-
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
1608-
int flags, Error **errp)
1607+
/*
1608+
* Create and open a block node.
1609+
*
1610+
* @options is a QDict of options to pass to the block drivers, or NULL for an
1611+
* empty set of options. The reference to the QDict belongs to the block layer
1612+
* after the call (even on failure), so if the caller intends to reuse the
1613+
* dictionary, it needs to use qobject_ref() before calling bdrv_open.
1614+
*/
1615+
BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
1616+
const char *node_name,
1617+
QDict *options, int flags,
1618+
Error **errp)
16091619
{
16101620
BlockDriverState *bs;
16111621
int ret;
16121622

16131623
bs = bdrv_new();
16141624
bs->open_flags = flags;
1615-
bs->explicit_options = qdict_new();
1616-
bs->options = qdict_new();
1625+
bs->options = options ?: qdict_new();
1626+
bs->explicit_options = qdict_clone_shallow(bs->options);
16171627
bs->opaque = NULL;
16181628

16191629
update_options_from_flags(bs->options, flags);
@@ -1631,6 +1641,13 @@ BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
16311641
return bs;
16321642
}
16331643

1644+
/* Create and open a block node. */
1645+
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
1646+
int flags, Error **errp)
1647+
{
1648+
return bdrv_new_open_driver_opts(drv, node_name, NULL, flags, errp);
1649+
}
1650+
16341651
QemuOptsList bdrv_runtime_opts = {
16351652
.name = "bdrv_common",
16361653
.head = QTAILQ_HEAD_INITIALIZER(bdrv_runtime_opts.head),
@@ -5102,29 +5119,61 @@ static void bdrv_delete(BlockDriverState *bs)
51025119
g_free(bs);
51035120
}
51045121

5105-
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
5122+
5123+
/*
5124+
* Replace @bs by newly created block node.
5125+
*
5126+
* @options is a QDict of options to pass to the block drivers, or NULL for an
5127+
* empty set of options. The reference to the QDict belongs to the block layer
5128+
* after the call (even on failure), so if the caller intends to reuse the
5129+
* dictionary, it needs to use qobject_ref() before calling bdrv_open.
5130+
*/
5131+
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
51065132
int flags, Error **errp)
51075133
{
5108-
BlockDriverState *new_node_bs;
5109-
Error *local_err = NULL;
5134+
ERRP_GUARD();
5135+
int ret;
5136+
BlockDriverState *new_node_bs = NULL;
5137+
const char *drvname, *node_name;
5138+
BlockDriver *drv;
5139+
5140+
drvname = qdict_get_try_str(options, "driver");
5141+
if (!drvname) {
5142+
error_setg(errp, "driver is not specified");
5143+
goto fail;
5144+
}
5145+
5146+
drv = bdrv_find_format(drvname);
5147+
if (!drv) {
5148+
error_setg(errp, "Unknown driver: '%s'", drvname);
5149+
goto fail;
5150+
}
5151+
5152+
node_name = qdict_get_try_str(options, "node-name");
51105153

5111-
new_node_bs = bdrv_open(NULL, NULL, node_options, flags, errp);
5112-
if (new_node_bs == NULL) {
5154+
new_node_bs = bdrv_new_open_driver_opts(drv, node_name, options, flags,
5155+
errp);
5156+
options = NULL; /* bdrv_new_open_driver() eats options */
5157+
if (!new_node_bs) {
51135158
error_prepend(errp, "Could not create node: ");
5114-
return NULL;
5159+
goto fail;
51155160
}
51165161

51175162
bdrv_drained_begin(bs);
5118-
bdrv_replace_node(bs, new_node_bs, &local_err);
5163+
ret = bdrv_replace_node(bs, new_node_bs, errp);
51195164
bdrv_drained_end(bs);
51205165

5121-
if (local_err) {
5122-
bdrv_unref(new_node_bs);
5123-
error_propagate(errp, local_err);
5124-
return NULL;
5166+
if (ret < 0) {
5167+
error_prepend(errp, "Could not replace node: ");
5168+
goto fail;
51255169
}
51265170

51275171
return new_node_bs;
5172+
5173+
fail:
5174+
qobject_unref(options);
5175+
bdrv_unref(new_node_bs);
5176+
return NULL;
51285177
}
51295178

51305179
/*

block/block-backend.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,12 @@ uint32_t blk_get_max_transfer(BlockBackend *blk)
19861986
return ROUND_DOWN(max, blk_get_request_alignment(blk));
19871987
}
19881988

1989+
int blk_get_max_hw_iov(BlockBackend *blk)
1990+
{
1991+
return MIN_NON_ZERO(blk->root->bs->bl.max_hw_iov,
1992+
blk->root->bs->bl.max_iov);
1993+
}
1994+
19891995
int blk_get_max_iov(BlockBackend *blk)
19901996
{
19911997
return blk->root->bs->bl.max_iov;

block/file-posix.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
12731273

12741274
ret = hdev_get_max_segments(s->fd, &st);
12751275
if (ret > 0) {
1276-
bs->bl.max_iov = ret;
1276+
bs->bl.max_hw_iov = ret;
12771277
}
12781278
}
12791279
}

block/io.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
136136
dst->min_mem_alignment = MAX(dst->min_mem_alignment,
137137
src->min_mem_alignment);
138138
dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov);
139+
dst->max_hw_iov = MIN_NON_ZERO(dst->max_hw_iov, src->max_hw_iov);
139140
}
140141

141142
typedef struct BdrvRefreshLimitsState {

hw/scsi/scsi-generic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
180180
page = r->req.cmd.buf[2];
181181
if (page == 0xb0) {
182182
uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
183-
uint32_t max_iov = blk_get_max_iov(s->conf.blk);
183+
uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk);
184184

185185
assert(max_transfer);
186186
max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size)

include/block/block.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
383383
const char *bdref_key, Error **errp);
384384
BlockDriverState *bdrv_open(const char *filename, const char *reference,
385385
QDict *options, int flags, Error **errp);
386+
BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
387+
const char *node_name,
388+
QDict *options, int flags,
389+
Error **errp);
386390
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
387391
int flags, Error **errp);
388392
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
@@ -751,9 +755,7 @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
751755
* bdrv_drained_begin:
752756
*
753757
* Begin a quiesced section for exclusive access to the BDS, by disabling
754-
* external request sources including NBD server and device model. Note that
755-
* this doesn't block timers or coroutines from submitting more requests, which
756-
* means block_job_pause is still necessary.
758+
* external request sources including NBD server, block jobs, and device model.
757759
*
758760
* This function can be recursive.
759761
*/

include/block/block_int.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,13 @@ typedef struct BlockLimits {
718718
*/
719719
uint64_t max_hw_transfer;
720720

721+
/* Maximal number of scatter/gather elements allowed by the hardware.
722+
* Applies whenever transfers to the device bypass the kernel I/O
723+
* scheduler, for example with SG_IO. If larger than max_iov
724+
* or if zero, blk_get_max_hw_iov will fall back to max_iov.
725+
*/
726+
int max_hw_iov;
727+
721728
/* memory alignment, in bytes so that no bounce buffer is needed */
722729
size_t min_mem_alignment;
723730

include/sysemu/block-backend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ uint32_t blk_get_request_alignment(BlockBackend *blk);
211211
uint32_t blk_get_max_transfer(BlockBackend *blk);
212212
uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
213213
int blk_get_max_iov(BlockBackend *blk);
214+
int blk_get_max_hw_iov(BlockBackend *blk);
214215
void blk_set_guest_block_size(BlockBackend *blk, int align);
215216
void *blk_try_blockalign(BlockBackend *blk, size_t size);
216217
void *blk_blockalign(BlockBackend *blk, size_t size);

storage-daemon/qemu-storage-daemon.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,12 @@ static void help(void)
9898
" export the specified block node over NBD\n"
9999
" (requires --nbd-server)\n"
100100
"\n"
101+
#ifdef CONFIG_FUSE
101102
" --export [type=]fuse,id=<id>,node-name=<node-name>,mountpoint=<file>\n"
102103
" [,growable=on|off][,writable=on|off]\n"
103104
" export the specified block node over FUSE\n"
104105
"\n"
106+
#endif /* CONFIG_FUSE */
105107
" --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
106108
" configure a QMP monitor\n"
107109
"\n"

tests/qemu-iotests/235

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import os
2424
import iotests
2525
from iotests import qemu_img_create, qemu_io, file_path, log
2626

27-
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
28-
2927
from qemu.machine import QEMUMachine
3028

3129
iotests.script_initialize(supported_fmts=['qcow2'])

0 commit comments

Comments
 (0)