[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 08/34] fuse: Allow growable exports
From: |
Kevin Wolf |
Subject: |
[PULL 08/34] fuse: Allow growable exports |
Date: |
Fri, 11 Dec 2020 18:07:46 +0100 |
From: Max Reitz <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>
Message-Id: <20201027190600.192171-5-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@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 430bc69f35..e819e70cac 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -129,10 +129,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.29.2
- [PULL 00/34] Block layer patches, Kevin Wolf, 2020/12/11
- [PULL 02/34] block/curl: Use lock guard macros, Kevin Wolf, 2020/12/11
- [PULL 01/34] block/accounting: Use lock guard macros, Kevin Wolf, 2020/12/11
- [PULL 04/34] block/iscsi: Use lock guard macros, Kevin Wolf, 2020/12/11
- [PULL 03/34] block/throttle-groups: Use lock guard macros, Kevin Wolf, 2020/12/11
- [PULL 06/34] fuse: Allow exporting BDSs via FUSE, Kevin Wolf, 2020/12/11
- [PULL 08/34] fuse: Allow growable exports,
Kevin Wolf <=
- [PULL 07/34] fuse: Implement standard FUSE operations, Kevin Wolf, 2020/12/11
- [PULL 05/34] meson: Detect libfuse, Kevin Wolf, 2020/12/11
- [PULL 09/34] fuse: (Partially) implement fallocate(), Kevin Wolf, 2020/12/11
- [PULL 10/34] fuse: Implement hole detection through lseek, Kevin Wolf, 2020/12/11
- [PULL 12/34] iotests: Do not pipe _make_test_img, Kevin Wolf, 2020/12/11
- [PULL 11/34] iotests: Do not needlessly filter _make_test_img, Kevin Wolf, 2020/12/11
- [PULL 13/34] iotests: Use convert -n in some cases, Kevin Wolf, 2020/12/11
- [PULL 15/34] iotests: Derive image names from $TEST_IMG, Kevin Wolf, 2020/12/11
- [PULL 14/34] iotests/046: Avoid renaming images, Kevin Wolf, 2020/12/11
- [PULL 17/34] iotests: Restrict some Python tests to file, Kevin Wolf, 2020/12/11