From nobody Mon Feb 9 16:35:04 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1603826033; cv=none; d=zohomail.com; s=zohoarc; b=htXJRyT8Pj1Mrpv+X5fEDtB1tszl53OmavBBhvhioXyL8j6VEmwCQZK/6eAPlFxMniETRXDpQpgQzz1uSaf0bVSBOAYX3PEz4LnZOECdpTIiwSGUcy6BVE3SR35EgNAKI5EsuxoA4Tiq3UG3FzFpirZLBjppE6wVsjb9NZfW+Xo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1603826033; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=g0XR/4o4qTngLot4S7dyPq/9b1QLApg4R7DOcp/mYcA=; b=i9EU9V1XKM2+1wqyPsfBqu+NBlhl2nv/JSWppTG56CfNwUmPXQ5MRXPEgpI27o9aOI+dTiVE7a3jKqGQjVqLheMX+PLrspCDvkF7QSH2BeR5tHUGwnobnRrSwfNW24kSyv9WV6+oROUuhTx4j1cQUlaPlM0JMTUbWH6c8dbEZbw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1603826033633947.4853936168146; Tue, 27 Oct 2020 12:13:53 -0700 (PDT) Received: from localhost ([::1]:35508 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kXUPo-0000of-9A for importer@patchew.org; Tue, 27 Oct 2020 15:13:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41982) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kXUIg-0000qm-Ob for qemu-devel@nongnu.org; Tue, 27 Oct 2020 15:06:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:58818) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kXUIe-0001IR-Ii for qemu-devel@nongnu.org; Tue, 27 Oct 2020 15:06:30 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-81-xakDI3a9NpKiifpYCFcQlg-1; Tue, 27 Oct 2020 15:06:25 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id EB4C1107ACF5; Tue, 27 Oct 2020 19:06:23 +0000 (UTC) Received: from localhost (unknown [10.40.193.195]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7CD4F55760; Tue, 27 Oct 2020 19:06:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1603825587; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g0XR/4o4qTngLot4S7dyPq/9b1QLApg4R7DOcp/mYcA=; b=MPb+IBGocUsM6zDoy6Ro5f1fq6xgR8rKsr11A7Zk8hACJG6aCVV1RZ6b8WKXWAUBu1JMsf CySl/aCKGRolf336FGosNVw3TTIeqRphcKFyNIUFnoyzcRpdhA/HogcYm64zIdG5gV3rrz DedQ/oE9Av2F6NUBv74YDVD3abAfk0c= X-MC-Unique: xakDI3a9NpKiifpYCFcQlg-1 From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH for-6.0 v3 04/20] fuse: Allow growable exports Date: Tue, 27 Oct 2020 20:05:44 +0100 Message-Id: <20201027190600.192171-5-mreitz@redhat.com> In-Reply-To: <20201027190600.192171-1-mreitz@redhat.com> References: <20201027190600.192171-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/27 01:06:06 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" 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 --- 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)' } =20 ## 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 { =20 char *mountpoint; bool writable; + bool growable; } FuseExport; =20 static GHashTable *exports; @@ -72,6 +73,19 @@ static int fuse_export_create(BlockExport *blk_exp, =20 assert(blk_exp_args->type =3D=3D BLOCK_EXPORT_TYPE_FUSE); =20 + /* 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 =3D blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE, + blk_shared_perm, errp); + if (ret < 0) { + return ret; + } + } + init_exports_table(); =20 /* @@ -102,6 +116,7 @@ static int fuse_export_create(BlockExport *blk_exp, =20 exp->mountpoint =3D g_strdup(args->mountpoint); exp->writable =3D blk_exp_args->writable; + exp->growable =3D args->growable; =20 ret =3D setup_fuse_export(exp, args->mountpoint, errp); if (ret < 0) { @@ -349,19 +364,24 @@ static int fuse_do_truncate(const FuseExport *exp, in= t64_t size, truncate_flags |=3D BDRV_REQ_ZERO_WRITE; } =20 - 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); =20 - ret =3D blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE, - blk_shared_perm, NULL); - if (ret < 0) { - return ret; + ret =3D blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE, + blk_shared_perm, NULL); + if (ret < 0) { + return ret; + } } =20 ret =3D blk_truncate(exp->common.blk, size, true, prealloc, truncate_flags, NULL); =20 - /* 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 permissi= on */ + blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_ab= ort); + } =20 return ret; } @@ -482,7 +502,15 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inod= e, const char *buf, } =20 if (offset + size > length) { - size =3D length - offset; + if (exp->growable) { + ret =3D fuse_do_truncate(exp, offset + size, true, PREALLOC_MO= DE_OFF); + if (ret < 0) { + fuse_reply_err(req, -ret); + return; + } + } else { + size =3D length - offset; + } } =20 ret =3D blk_pwrite(exp->common.blk, offset, buf, size, 0); --=20 2.26.2