All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxim Patlasov <mpatlasov@parallels.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: fuse-devel <fuse-devel@lists.sourceforge.net>,
	Linux-Fsdevel <linux-fsdevel@vger.kernel.org>,
	Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 2/4] fuse: writepages: crop secondary requests
Date: Thu, 3 Oct 2013 20:22:20 +0400	[thread overview]
Message-ID: <524D99BC.1030007@parallels.com> (raw)
In-Reply-To: <CAJfpeguzpFcZnZV7nfbeETRKcu9zn1AA--N6cOA2qF+zMgEANA@mail.gmail.com>

On 10/03/2013 08:09 PM, Miklos Szeredi wrote:
> On Thu, Oct 3, 2013 at 5:50 PM, Maxim Patlasov <mpatlasov@parallels.com> wrote:
>> On 10/03/2013 07:14 PM, Miklos Szeredi wrote:
>>> On Thu, Oct 03, 2013 at 05:28:30PM +0400, Maxim Patlasov wrote:
>>>
>>>> 1. There is an in-flight primary request with a chain of secondary ones.
>>>> 2. User calls ftruncate(2) to extend file; fuse_set_nowrite() makes
>>>> fi->writectr negative and starts waiting for completion of that
>>>> in-flight request
>>>> 3. Userspace fuse daemon ACKs the request and fuse_writepage_end()
>>>> is called; it calls __fuse_flush_writepages(), but the latter does
>>>> nothing because fi->writectr < 0
>>>> 4. fuse_do_setattr() proceeds extending i_size and calling
>>>> __fuse_release_nowrite(). But now new (increased) i_size will be
>>>> used as 'crop' arg of __fuse_flush_writepages()
>>>>
>>>> stale data can leak to the server.
>>> So, lets do this then: skip fuse_flush_writepages() and call
>>> fuse_send_writepage() directly.  It will ignore the NOWRITE logic, but
>>> that's
>>> okay, this happens rarely and cannot happen more than once in a row.
>>>
>>> Does this look good?
>>
>> Yes, but let's at least add a comment explaining why it's safe. There are
>> three different cases and what you write above explains only one of them:
>>
>> 1st case (trivial): there are no concurrent activities using
>> fuse_set/release_nowrite. Then we're on safe side because
>> fuse_flush_writepages() would call fuse_send_writepage() anyway.
>> 2nd case: someone called fuse_set_nowrite and it is waiting now for
>> completion of all in-flight requests. Here what you wrote about "happening
>> rarely and no more than once" is applicable.
>> 3rd case: someone (e.g. fuse_do_setattr()) is in the middle of
>> fuse_set_nowrite..fuse_release_nowrite section. The fact that
>> fuse_set_nowrite returned implies that all in-flight requests were completed
>> along with all its secondary requests (because we increment writectr for a
>> secondry before decrementing it for the primary -- that's how
>> fuse_writepage_end is implemeted). Further requests are blocked by negative
>> writectr. Hence there cannot be any in-flight requests and no invocations of
>> fuse_writepage_end while we're in fuse_set_nowrite..fuse_release_nowrite
>> section.
>>
>> It looks obvious now, but I'm not sure we'll able to recollect it later.
> Added your analysis as a comment and all patches pushed to writepages.v2.

Great! So I can proceed with re-basing the rest of 
writeback-cache-policy pile to writepages.v2 soon.

>
>>> Can you actually trigger this path with your testing?
>>
>> No.
> Hmm, did you do any testing with the wait-for-page-writeback disabled
> in fuse_mkwrite()?

Yes, of course. I've been doing that for a week on two very different 
h/w nodes, but I'm using ordinary fsx (not some artificial hand-crafted 
mmap-writer) and I usually get only a dozen "rewrite: 1" messages per 
night. This is enough to make sure that rewrite code main-path is OK, 
but not enough to be sure that all corner cases are covered.

Thanks,
Maxim


  reply	other threads:[~2013-10-03 16:22 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-02 17:37 [PATCH 0/4] fuse: fixes for fuse_writepage_in_flight() and friends -v2 Maxim Patlasov
2013-10-02 17:38 ` [PATCH 1/4] fuse: writepages: roll back changes if request not found Maxim Patlasov
2013-10-02 17:38 ` [PATCH 2/4] fuse: writepages: crop secondary requests Maxim Patlasov
2013-10-03  9:57   ` Miklos Szeredi
2013-10-03 13:28     ` Maxim Patlasov
2013-10-03 15:14       ` Miklos Szeredi
2013-10-03 15:50         ` Maxim Patlasov
2013-10-03 16:09           ` Miklos Szeredi
2013-10-03 16:22             ` Maxim Patlasov [this message]
2013-10-09  8:20               ` [fuse-devel] " Maxim Patlasov
2013-10-09 15:37                 ` Maxim Patlasov
2013-10-02 17:38 ` [PATCH 3/4] fuse: writepage: update bdi writeout when deleting secondary request Maxim Patlasov
2013-10-03 10:26   ` Miklos Szeredi
2013-10-03 13:46     ` Maxim Patlasov
2013-10-02 17:38 ` [PATCH 4/4] fuse: writepages: protect secondary requests from fuse file release Maxim Patlasov
2013-10-03 10:33   ` Miklos Szeredi

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=524D99BC.1030007@parallels.com \
    --to=mpatlasov@parallels.com \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /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.