From nobody Tue Feb 10 21:19:08 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1525903087215286.8560693960401; Wed, 9 May 2018 14:58:07 -0700 (PDT) Received: from localhost ([::1]:59203 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fGX66-0002bo-Jc for importer@patchew.org; Wed, 09 May 2018 17:58:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49774) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fGX1z-0007IT-PV for qemu-devel@nongnu.org; Wed, 09 May 2018 17:53:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fGX1y-0006o9-Rt for qemu-devel@nongnu.org; Wed, 09 May 2018 17:53:51 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:54630 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fGX1v-0006mN-AI; Wed, 09 May 2018 17:53:47 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5306A8D6DA; Wed, 9 May 2018 21:53:46 +0000 (UTC) Received: from localhost (unknown [10.40.205.23]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EDBB62166BAD; Wed, 9 May 2018 21:53:45 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Wed, 9 May 2018 23:53:35 +0200 Message-Id: <20180509215336.31304-3-mreitz@redhat.com> In-Reply-To: <20180509215336.31304-1-mreitz@redhat.com> References: <20180509215336.31304-1-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Wed, 09 May 2018 21:53:46 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Wed, 09 May 2018 21:53:46 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'mreitz@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v2 2/3] block/file-posix: File locking during creation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When creating a file, we should take the WRITE and RESIZE permissions. We do not need either for the creation itself, but we do need them for clearing and resizing it. So we can take the proper permissions by replacing O_TRUNC with an explicit truncation to 0, and by taking the appropriate file locks between those two steps. Signed-off-by: Max Reitz Reviewed-by: Fam Zheng --- block/file-posix.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index c98a4a1556..370a4833e4 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1992,6 +1992,7 @@ static int raw_co_create(BlockdevCreateOptions *optio= ns, Error **errp) { BlockdevCreateOptionsFile *file_opts; int fd; + int perm, shared; int result =3D 0; =20 /* Validate options and set default values */ @@ -2006,14 +2007,44 @@ static int raw_co_create(BlockdevCreateOptions *opt= ions, Error **errp) } =20 /* Create file */ - fd =3D qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_TRUNC | O_B= INARY, - 0644); + fd =3D qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_BINARY, 064= 4); if (fd < 0) { result =3D -errno; error_setg_errno(errp, -result, "Could not create file"); goto out; } =20 + /* Take permissions: We want to discard everything, so we need + * BLK_PERM_WRITE; and truncation to the desired size requires + * BLK_PERM_RESIZE. + * On the other hand, we cannot share the RESIZE permission + * because we promise that after this function, the file has the + * size given in the options. If someone else were to resize it + * concurrently, we could not guarantee that. + * Note that after this function, we can no longer guarantee that + * the file is not touched by a third party, so it may be resized + * then. */ + perm =3D BLK_PERM_WRITE | BLK_PERM_RESIZE; + shared =3D BLK_PERM_ALL & ~BLK_PERM_RESIZE; + + /* Step one: Take locks */ + result =3D raw_apply_lock_bytes(fd, perm, shared, false, errp); + if (result < 0) { + goto out_close; + } + + /* Step two: Check that nobody else has taken conflicting locks */ + result =3D raw_check_lock_bytes(fd, perm, shared, errp); + if (result < 0) { + goto out_close; + } + + /* Clear the file by truncating it to 0 */ + result =3D raw_regular_truncate(fd, 0, PREALLOC_MODE_OFF, errp); + if (result < 0) { + goto out_close; + } + if (file_opts->nocow) { #ifdef __linux__ /* Set NOCOW flag to solve performance issue on fs like btrfs. @@ -2029,6 +2060,8 @@ static int raw_co_create(BlockdevCreateOptions *optio= ns, Error **errp) #endif } =20 + /* Resize and potentially preallocate the file to the desired + * final size */ result =3D raw_regular_truncate(fd, file_opts->size, file_opts->preall= ocation, errp); if (result < 0) { --=20 2.14.3