All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fam Zheng <famz@redhat.com>
To: Max Reitz <mreitz@redhat.com>
Cc: qemu-block@nongnu.org, Kevin Wolf <kwolf@redhat.com>,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/3] block/file-posix: File locking during creation
Date: Fri, 27 Apr 2018 14:22:21 +0800	[thread overview]
Message-ID: <20180427062221.GD4217@lemon.usersys.redhat.com> (raw)
In-Reply-To: <20180420220913.27000-3-mreitz@redhat.com>

On Sat, 04/21 00:09, Max Reitz wrote:
> 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 <mreitz@redhat.com>
> ---
>  block/file-posix.c | 41 +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 39 insertions(+), 2 deletions(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index c98a4a1556..ed7932d6e8 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1992,6 +1992,7 @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
>  {
>      BlockdevCreateOptionsFile *file_opts;
>      int fd;
> +    int perm, shared;
>      int result = 0;
>  
>      /* Validate options and set default values */
> @@ -2006,14 +2007,48 @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
>      }
>  
>      /* Create file */
> -    fd = qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
> -                   0644);
> +    fd = qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_BINARY, 0644);
>      if (fd < 0) {
>          result = -errno;
>          error_setg_errno(errp, -result, "Could not create file");
>          goto out;
>      }
>  
> +    /* 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. */

Strictly speaking, we do close(fd) before this function returns so the lock is
lost and race can happen.

> +    perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
> +    shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
> +
> +    /* Step one: Take locks in shared mode */
> +    result = raw_apply_lock_bytes(fd, perm, shared, false, errp);
> +    if (result < 0) {
> +        goto out_close;
> +    }
> +
> +    /* Step two: Try to get them exclusively */
> +    result = raw_check_lock_bytes(fd, perm, shared, errp);
> +    if (result < 0) {
> +        goto out_close;
> +    }
> +
> +    /* Step three: Downgrade them to shared again, and keep
> +     *             them that way until we are done */
> +    result = raw_apply_lock_bytes(fd, perm, shared, true, errp);

You comment it as "downgrade to shared" but what this actually does in addition
to step one is to "unlock" unneeded bytes which we haven't locked anyway. So I'm
confused why we need this stop. IIUC no downgrading is necessary after step one
and step two: only necessary shared locks are acquired in step one, and step two
is read-only op (F_OFD_GETLK).

> +    if (result < 0) {
> +        goto out_close;
> +    }
> +
> +    /* Clear the file by truncating it to 0 */
> +    result = 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 +2064,8 @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
>  #endif
>      }
>  
> +    /* Resize and potentially preallocate the file to the desired
> +     * final size */
>      result = raw_regular_truncate(fd, file_opts->size, file_opts->preallocation,
>                                    errp);
>      if (result < 0) {
> -- 
> 2.14.3
> 
> 

Fam

  reply	other threads:[~2018-04-27  6:22 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-20 22:09 [Qemu-devel] [PATCH 0/3] block/file-posix: File locking during creation Max Reitz
2018-04-20 22:09 ` [Qemu-devel] [PATCH 1/3] block/file-posix: Pass FD to locking helpers Max Reitz
2018-04-27  6:24   ` Fam Zheng
2018-04-20 22:09 ` [Qemu-devel] [PATCH 2/3] block/file-posix: File locking during creation Max Reitz
2018-04-27  6:22   ` Fam Zheng [this message]
2018-04-28 11:03     ` Max Reitz
2018-05-03  6:45       ` Fam Zheng
2018-05-04 13:45         ` Max Reitz
2018-05-07  7:23           ` Fam Zheng
2018-04-20 22:09 ` [Qemu-devel] [PATCH 3/3] iotests: Add creation test to 153 Max Reitz
2018-04-27  6:24   ` Fam Zheng
2018-04-23 13:19 ` [Qemu-devel] [Qemu-block] [PATCH 0/3] block/file-posix: File locking during creation Alberto Garcia
2018-04-23 15:56   ` Max Reitz

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=20180427062221.GD4217@lemon.usersys.redhat.com \
    --to=famz@redhat.com \
    --cc=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.