From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com
Subject: [PATCH 06/29] qemu-nbd: Use raw block driver for --offset
Date: Mon, 7 Sep 2020 20:19:48 +0200 [thread overview]
Message-ID: <20200907182011.521007-7-kwolf@redhat.com> (raw)
In-Reply-To: <20200907182011.521007-1-kwolf@redhat.com>
Instead of implementing qemu-nbd --offset in the NBD code, just put a
raw block node with the requested offset on top of the user image and
rely on that doing the job.
This does not only simplify the nbd_export_new() interface and bring it
closer to the set of options that the nbd-server-add QMP command offers,
but in fact it also eliminates a potential source for bugs in the NBD
code which previously had to add the offset manually in all relevant
places.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
include/block/nbd.h | 4 ++--
blockdev-nbd.c | 9 +--------
nbd/server.c | 33 ++++++++++++++++-----------------
qemu-nbd.c | 27 ++++++++++++---------------
4 files changed, 31 insertions(+), 42 deletions(-)
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 7698453fb2..451f399b0a 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -331,8 +331,8 @@ typedef struct NBDExport NBDExport;
typedef struct NBDClient NBDClient;
BlockExport *nbd_export_create(BlockExportOptions *exp_args, Error **errp);
-NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
- uint64_t size, const char *name, const char *desc,
+NBDExport *nbd_export_new(BlockDriverState *bs,
+ const char *name, const char *desc,
const char *bitmap, bool readonly, bool shared,
void (*close)(NBDExport *), bool writethrough,
BlockBackend *on_eject_blk, Error **errp);
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 47b04f166a..96cb0100e9 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -154,7 +154,6 @@ BlockExport *nbd_export_create(BlockExportOptions *exp_args, Error **errp)
BlockDriverState *bs = NULL;
BlockBackend *on_eject_blk;
NBDExport *exp = NULL;
- int64_t len;
AioContext *aio_context;
assert(exp_args->type == BLOCK_EXPORT_TYPE_NBD);
@@ -192,12 +191,6 @@ BlockExport *nbd_export_create(BlockExportOptions *exp_args, Error **errp)
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
- len = bdrv_getlength(bs);
- if (len < 0) {
- error_setg_errno(errp, -len,
- "Failed to determine the NBD export's length");
- goto out;
- }
if (!arg->has_writable) {
arg->writable = false;
@@ -206,7 +199,7 @@ BlockExport *nbd_export_create(BlockExportOptions *exp_args, Error **errp)
arg->writable = false;
}
- exp = nbd_export_new(bs, 0, len, arg->name, arg->description, arg->bitmap,
+ exp = nbd_export_new(bs, arg->name, arg->description, arg->bitmap,
!arg->writable, !arg->writable,
NULL, false, on_eject_blk, errp);
if (!exp) {
diff --git a/nbd/server.c b/nbd/server.c
index f5af93c253..33aaca918c 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -89,7 +89,6 @@ struct NBDExport {
BlockBackend *blk;
char *name;
char *description;
- uint64_t dev_offset;
uint64_t size;
uint16_t nbdflags;
QTAILQ_HEAD(, NBDClient) clients;
@@ -1507,8 +1506,8 @@ static void nbd_eject_notifier(Notifier *n, void *data)
aio_context_release(aio_context);
}
-NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
- uint64_t size, const char *name, const char *desc,
+NBDExport *nbd_export_new(BlockDriverState *bs,
+ const char *name, const char *desc,
const char *bitmap, bool readonly, bool shared,
void (*close)(NBDExport *), bool writethrough,
BlockBackend *on_eject_blk, Error **errp)
@@ -1516,9 +1515,17 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
AioContext *ctx;
BlockBackend *blk;
NBDExport *exp;
+ int64_t size;
uint64_t perm;
int ret;
+ size = bdrv_getlength(bs);
+ if (size < 0) {
+ error_setg_errno(errp, -size,
+ "Failed to determine the NBD export's length");
+ return NULL;
+ }
+
exp = g_new0(NBDExport, 1);
exp->common = (BlockExport) {
.drv = &blk_exp_nbd,
@@ -1553,8 +1560,6 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
exp->refcount = 1;
QTAILQ_INIT(&exp->clients);
exp->blk = blk;
- assert(dev_offset <= INT64_MAX);
- exp->dev_offset = dev_offset;
exp->name = g_strdup(name);
assert(!desc || strlen(desc) <= NBD_MAX_STRING_SIZE);
exp->description = g_strdup(desc);
@@ -1569,7 +1574,6 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
exp->nbdflags |= (NBD_FLAG_SEND_TRIM | NBD_FLAG_SEND_WRITE_ZEROES |
NBD_FLAG_SEND_FAST_ZERO);
}
- assert(size <= INT64_MAX - dev_offset);
exp->size = QEMU_ALIGN_DOWN(size, BDRV_SECTOR_SIZE);
if (bitmap) {
@@ -1928,8 +1932,7 @@ static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
stl_be_p(&chunk.length, pnum);
ret = nbd_co_send_iov(client, iov, 1, errp);
} else {
- ret = blk_pread(exp->blk, offset + progress + exp->dev_offset,
- data + progress, pnum);
+ ret = blk_pread(exp->blk, offset + progress, data + progress, pnum);
if (ret < 0) {
error_setg_errno(errp, -ret, "reading from file failed");
break;
@@ -2303,8 +2306,7 @@ static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request,
data, request->len, errp);
}
- ret = blk_pread(exp->blk, request->from + exp->dev_offset, data,
- request->len);
+ ret = blk_pread(exp->blk, request->from, data, request->len);
if (ret < 0) {
return nbd_send_generic_reply(client, request->handle, ret,
"reading from file failed", errp);
@@ -2339,7 +2341,7 @@ static coroutine_fn int nbd_do_cmd_cache(NBDClient *client, NBDRequest *request,
assert(request->type == NBD_CMD_CACHE);
- ret = blk_co_preadv(exp->blk, request->from + exp->dev_offset, request->len,
+ ret = blk_co_preadv(exp->blk, request->from, request->len,
NULL, BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH);
return nbd_send_generic_reply(client, request->handle, ret,
@@ -2370,8 +2372,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
if (request->flags & NBD_CMD_FLAG_FUA) {
flags |= BDRV_REQ_FUA;
}
- ret = blk_pwrite(exp->blk, request->from + exp->dev_offset,
- data, request->len, flags);
+ ret = blk_pwrite(exp->blk, request->from, data, request->len, flags);
return nbd_send_generic_reply(client, request->handle, ret,
"writing to file failed", errp);
@@ -2392,8 +2393,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
int align = client->check_align ?: 1;
int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES,
align));
- ret = blk_pwrite_zeroes(exp->blk, request->from + exp->dev_offset,
- len, flags);
+ ret = blk_pwrite_zeroes(exp->blk, request->from, len, flags);
request->len -= len;
request->from += len;
}
@@ -2416,8 +2416,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
int align = client->check_align ?: 1;
int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES,
align));
- ret = blk_co_pdiscard(exp->blk, request->from + exp->dev_offset,
- len);
+ ret = blk_co_pdiscard(exp->blk, request->from, len);
request->len -= len;
request->from += len;
}
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 33476a1000..1752daa4c4 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -524,7 +524,6 @@ int main(int argc, char **argv)
const char *port = NULL;
char *sockpath = NULL;
char *device = NULL;
- int64_t fd_size;
QemuOpts *sn_opts = NULL;
const char *sn_id_or_name = NULL;
const char *sopt = "hVb:o:p:rsnc:dvk:e:f:tl:x:T:D:B:L";
@@ -1037,6 +1036,17 @@ int main(int argc, char **argv)
}
bs = blk_bs(blk);
+ if (dev_offset) {
+ QDict *raw_opts = qdict_new();
+ qdict_put_str(raw_opts, "driver", "raw");
+ qdict_put_str(raw_opts, "file", bs->node_name);
+ qdict_put_int(raw_opts, "offset", dev_offset);
+ bs = bdrv_open(NULL, NULL, raw_opts, flags, &error_fatal);
+ blk_remove_bs(blk);
+ blk_insert_bs(blk, bs, &error_fatal);
+ bdrv_unref(bs);
+ }
+
blk_set_enable_write_cache(blk, !writethrough);
if (sn_opts) {
@@ -1054,21 +1064,8 @@ int main(int argc, char **argv)
}
bs->detect_zeroes = detect_zeroes;
- fd_size = blk_getlength(blk);
- if (fd_size < 0) {
- error_report("Failed to determine the image length: %s",
- strerror(-fd_size));
- exit(EXIT_FAILURE);
- }
-
- if (dev_offset >= fd_size) {
- error_report("Offset (%" PRIu64 ") has to be smaller than the image "
- "size (%" PRId64 ")", dev_offset, fd_size);
- exit(EXIT_FAILURE);
- }
- fd_size -= dev_offset;
- export = nbd_export_new(bs, dev_offset, fd_size, export_name,
+ export = nbd_export_new(bs, export_name,
export_description, bitmap, readonly, shared > 1,
nbd_export_closed, writethrough, NULL,
&error_fatal);
--
2.25.4
next prev parent reply other threads:[~2020-09-07 18:23 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-07 18:19 [PATCH 00/29] block/export: Add infrastructure and QAPI for block exports Kevin Wolf
2020-09-07 18:19 ` [PATCH 01/29] nbd: Remove unused nbd_export_get_blockdev() Kevin Wolf
2020-09-07 18:19 ` [PATCH 02/29] qapi: Create block-export module Kevin Wolf
2020-09-07 18:19 ` [PATCH 03/29] qapi: Rename BlockExport to BlockExportOptions Kevin Wolf
2020-09-07 18:19 ` [PATCH 04/29] block/export: Add BlockExport infrastructure and block-export-add Kevin Wolf
2020-09-10 10:16 ` Max Reitz
2020-09-07 18:19 ` [PATCH 05/29] qemu-storage-daemon: Use qmp_block_export_add() Kevin Wolf
2020-09-07 18:19 ` Kevin Wolf [this message]
2020-09-07 18:19 ` [PATCH 07/29] block/export: Remove magic from block-export-add Kevin Wolf
2020-09-10 10:53 ` Max Reitz
2020-09-07 18:19 ` [PATCH 08/29] nbd: Add max-connections to nbd-server-start Kevin Wolf
2020-09-07 18:19 ` [PATCH 09/29] nbd: Add writethrough to block-export-add Kevin Wolf
2020-09-10 11:15 ` Max Reitz
2020-09-07 18:19 ` [PATCH 10/29] nbd: Remove NBDExport.close callback Kevin Wolf
2020-09-07 18:19 ` [PATCH 11/29] qemu-nbd: Use blk_exp_add() to create the export Kevin Wolf
2020-09-07 18:19 ` [PATCH 12/29] nbd/server: Simplify export shutdown Kevin Wolf
2020-09-07 18:19 ` [PATCH 13/29] block/export: Move refcount from NBDExport to BlockExport Kevin Wolf
2020-09-07 18:19 ` [PATCH 14/29] block/export: Move AioContext " Kevin Wolf
2020-09-10 11:52 ` Max Reitz
2020-09-07 18:19 ` [PATCH 15/29] block/export: Add node-name to BlockExportOptions Kevin Wolf
2020-09-10 12:35 ` Max Reitz
2020-09-07 18:19 ` [PATCH 16/29] block/export: Allocate BlockExport in blk_exp_add() Kevin Wolf
2020-09-16 10:56 ` Max Reitz
2020-09-07 18:19 ` [PATCH 17/29] block/export: Add blk_exp_close_all(_type) Kevin Wolf
2020-09-10 13:22 ` Max Reitz
2020-09-07 18:20 ` [PATCH 18/29] block/export: Add 'id' option to block-export-add Kevin Wolf
2020-09-10 13:26 ` Max Reitz
2020-09-07 18:20 ` [PATCH 19/29] block/export: Move strong user reference to block_exports Kevin Wolf
2020-09-10 13:33 ` Max Reitz
2020-09-10 13:36 ` Max Reitz
2020-09-07 18:20 ` [PATCH 20/29] block/export: Add block-export-del Kevin Wolf
2020-09-07 18:20 ` [PATCH 21/29] block/export: Add BLOCK_EXPORT_DELETED event Kevin Wolf
2020-09-10 14:04 ` Max Reitz
2020-09-10 15:12 ` Max Reitz
2020-09-16 14:57 ` Max Reitz
2020-09-07 18:20 ` [PATCH 22/29] block/export: Move blk to BlockExport Kevin Wolf
2020-09-07 18:20 ` [PATCH 23/29] block/export: Create BlockBackend in blk_exp_add() Kevin Wolf
2020-09-10 15:09 ` Max Reitz
2020-09-07 18:20 ` [PATCH 24/29] block/export: Add query-block-exports Kevin Wolf
2020-09-10 15:10 ` Max Reitz
2020-09-07 18:20 ` [PATCH 25/29] block/export: Move writable to BlockExportOptions Kevin Wolf
2020-09-10 15:15 ` Max Reitz
2020-09-07 18:20 ` [PATCH 26/29] nbd: Merge nbd_export_new() and nbd_export_create() Kevin Wolf
2020-09-10 15:30 ` Max Reitz
2020-09-07 18:20 ` [PATCH 27/29] nbd: Deprecate nbd-server-add/remove Kevin Wolf
2020-09-10 15:34 ` Max Reitz
2020-09-23 16:19 ` Kevin Wolf
2020-09-07 18:20 ` [PATCH 28/29] iotests: Factor out qemu_tool_pipe_and_status() Kevin Wolf
2020-09-10 15:45 ` Max Reitz
2020-09-07 18:20 ` [PATCH 29/29] iotests: Test block-export-* QMP interface Kevin Wolf
2020-09-10 16:11 ` Max Reitz
2020-09-08 8:38 ` [PATCH 00/29] block/export: Add infrastructure and QAPI for block exports Markus Armbruster
2020-09-08 12:29 ` Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200907182011.521007-7-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.