From: Max Reitz <mreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@redhat.com>,
Max Reitz <mreitz@redhat.com>
Subject: [PATCH for-6.0 v3 04/20] fuse: Allow growable exports
Date: Tue, 27 Oct 2020 20:05:44 +0100 [thread overview]
Message-ID: <20201027190600.192171-5-mreitz@redhat.com> (raw)
In-Reply-To: <20201027190600.192171-1-mreitz@redhat.com>
These will behave more like normal files in that writes beyond the EOF
will automatically grow the export size.
As an optimization, keep the RESIZE permission for growable exports so
we do not have to take it for every post-EOF write. (This permission is
not released when the export is destroyed, because at that point the
BlockBackend is destroyed altogether anyway.)
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
qapi/block-export.json | 6 +++++-
block/export/fuse.c | 44 ++++++++++++++++++++++++++++++++++--------
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/qapi/block-export.json b/qapi/block-export.json
index aecf052c07..140ba0d221 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -112,10 +112,14 @@
# @mountpoint: Path on which to export the block device via FUSE.
# This must point to an existing regular file.
#
+# @growable: Whether writes beyond the EOF should grow the block node
+# accordingly. (default: false)
+#
# Since: 6.0
##
{ 'struct': 'BlockExportOptionsFuse',
- 'data': { 'mountpoint': 'str' },
+ 'data': { 'mountpoint': 'str',
+ '*growable': 'bool' },
'if': 'defined(CONFIG_FUSE)' }
##
diff --git a/block/export/fuse.c b/block/export/fuse.c
index d995829ab7..92d2f50bcc 100644
--- a/block/export/fuse.c
+++ b/block/export/fuse.c
@@ -45,6 +45,7 @@ typedef struct FuseExport {
char *mountpoint;
bool writable;
+ bool growable;
} FuseExport;
static GHashTable *exports;
@@ -72,6 +73,19 @@ static int fuse_export_create(BlockExport *blk_exp,
assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE);
+ /* For growable exports, take the RESIZE permission */
+ if (args->growable) {
+ uint64_t blk_perm, blk_shared_perm;
+
+ blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
+
+ ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
+ blk_shared_perm, errp);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
init_exports_table();
/*
@@ -102,6 +116,7 @@ static int fuse_export_create(BlockExport *blk_exp,
exp->mountpoint = g_strdup(args->mountpoint);
exp->writable = blk_exp_args->writable;
+ exp->growable = args->growable;
ret = setup_fuse_export(exp, args->mountpoint, errp);
if (ret < 0) {
@@ -349,19 +364,24 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
truncate_flags |= BDRV_REQ_ZERO_WRITE;
}
- blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
+ /* Growable exports have a permanent RESIZE permission */
+ if (!exp->growable) {
+ blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
- ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
- blk_shared_perm, NULL);
- if (ret < 0) {
- return ret;
+ ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
+ blk_shared_perm, NULL);
+ if (ret < 0) {
+ return ret;
+ }
}
ret = blk_truncate(exp->common.blk, size, true, prealloc,
truncate_flags, NULL);
- /* Must succeed, because we are only giving up the RESIZE permission */
- blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
+ if (!exp->growable) {
+ /* Must succeed, because we are only giving up the RESIZE permission */
+ blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
+ }
return ret;
}
@@ -482,7 +502,15 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
}
if (offset + size > length) {
- size = length - offset;
+ if (exp->growable) {
+ ret = fuse_do_truncate(exp, offset + size, true, PREALLOC_MODE_OFF);
+ if (ret < 0) {
+ fuse_reply_err(req, -ret);
+ return;
+ }
+ } else {
+ size = length - offset;
+ }
}
ret = blk_pwrite(exp->common.blk, offset, buf, size, 0);
--
2.26.2
next prev parent reply other threads:[~2020-10-27 19:13 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-27 19:05 [PATCH for-6.0 v3 00/20] block/export: Allow exporting BDSs via FUSE Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 01/20] meson: Detect libfuse Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 02/20] fuse: Allow exporting BDSs via FUSE Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 03/20] fuse: Implement standard FUSE operations Max Reitz
2020-10-27 19:05 ` Max Reitz [this message]
2020-10-27 19:05 ` [PATCH for-6.0 v3 05/20] fuse: (Partially) implement fallocate() Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 06/20] fuse: Implement hole detection through lseek Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 07/20] iotests: Do not needlessly filter _make_test_img Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 08/20] iotests: Do not pipe _make_test_img Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 09/20] iotests: Use convert -n in some cases Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 10/20] iotests/046: Avoid renaming images Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 11/20] iotests: Derive image names from $TEST_IMG Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 12/20] iotests/091: Use _cleanup_qemu instad of "wait" Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 13/20] iotests: Restrict some Python tests to file Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 14/20] iotests: Let _make_test_img guess $TEST_IMG_FILE Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 15/20] iotests/287: Clean up subshell test image Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 16/20] storage-daemon: Call bdrv_close_all() on exit Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 17/20] iotests: Give access to the qemu-storage-daemon Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 18/20] iotests: Allow testing FUSE exports Max Reitz
2020-10-27 19:05 ` [PATCH for-6.0 v3 19/20] iotests: Enable fuse for many tests Max Reitz
2020-10-27 19:06 ` [PATCH for-6.0 v3 20/20] iotests/308: Add test for FUSE exports Max Reitz
2020-12-07 15:15 ` [PATCH for-6.0 v3 00/20] block/export: Allow exporting BDSs via FUSE 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=20201027190600.192171-5-mreitz@redhat.com \
--to=mreitz@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).