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/5] fuse: writepages: crop secondary requests on send -v2
Date: Wed, 2 Oct 2013 19:46:39 +0400 [thread overview]
Message-ID: <524C3FDF.5030201@parallels.com> (raw)
In-Reply-To: <CAJfpegvdeea0rPTEkNE6bRmYYPzxuJ2aAj0fZ80e53ic+K-jYg@mail.gmail.com>
On 10/02/2013 07:07 PM, Miklos Szeredi wrote:
> On Wed, Oct 2, 2013 at 1:17 PM, Maxim Patlasov <MPatlasov@parallels.com> wrote:
>> If writeback happens while fuse is in FUSE_NOWRITE condition, the request
>> will be queued but not processed immediately (see fuse_flush_writepages()).
>> Until FUSE_NOWRITE becomes relaxed, more writebacks can happen. They will
>> be queued as "secondary" requests to that first ("primary") request.
>>
>> When FUSE_NOWRITE is relaxed and fuse_send_writepage() is called, it must
>> crop both primary and secondary requests according to the actual i_size.
>> Otherwise, if only primary is cropped, an extending write(2) may increase
>> i_size soon and then secondary requests won't be cropped properly. The result
>> would be stale data written to the server to a file offset where zeros must be.
>>
>> Changed in v2:
>> - avoid NULL pointer dereference in fuse_drop_writepage().
>>
>> Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com>
>> ---
>> fs/fuse/file.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--------
>> 1 file changed, 55 insertions(+), 9 deletions(-)
>>
>> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
>> index 575e44f..89a2e76 100644
>> --- a/fs/fuse/file.c
>> +++ b/fs/fuse/file.c
>> @@ -1435,6 +1435,51 @@ static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req)
>> wake_up(&fi->page_waitq);
>> }
>>
>> +/* Drop list of secondary writepage requests */
>> +static void fuse_drop_writepage(struct fuse_conn *fc, struct fuse_req *req)
>> +{
>> + struct backing_dev_info *bdi = req ?
>> + req->inode->i_mapping->backing_dev_info : NULL;
>> +
>> + while (req) {
>> + struct fuse_req *next = req->misc.write.next;
>> + dec_bdi_stat(bdi, BDI_WRITEBACK);
>> + dec_zone_page_state(req->pages[0], NR_WRITEBACK_TEMP);
>> + fuse_writepage_free(fc, req);
>> + fuse_put_request(fc, req);
>> + req = next;
>> + }
>> +}
>> +
>> +/* Crop the misc.write.in.size of parent and secondary writepage requests */
>> +static bool fuse_crop_writepage(struct fuse_conn *fc, struct fuse_req *req,
>> + loff_t size, struct fuse_req **drop_list)
>> +{
>> + if (req->misc.write.in.offset >= size)
>> + return true;
>> +
>> + while (req) {
>> + struct fuse_req *next = req->misc.write.next;
>> + struct fuse_write_in *inarg = &req->misc.write.in;
>> + __u64 data_size = inarg->size ? :
>> + req->num_pages * PAGE_CACHE_SIZE;
>> +
>> + if (inarg->offset + data_size <= size) {
>> + inarg->size = data_size;
>> + } else if (inarg->offset < size) {
>> + inarg->size = size - inarg->offset;
>> + } else {
>> + /* Got truncated off completely */
>> + req->misc.write.next = *drop_list;
>> + *drop_list = req;
> This corrupts the list (the req is not taken off the list before being
> added to another). It could be fixed, but why not check this instead
> in fuse_writepage_end() before queuing the next request?
Nice idea. This will make next patch ("crop on attach") redundant. I'll
resend updated patch-set.
Thanks,
Maxim
next prev parent reply other threads:[~2013-10-02 15:46 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-02 11:00 [PATCH 0/5] fuse: fixes for fuse_writepage_in_flight() and friends Maxim Patlasov
2013-10-02 11:01 ` [PATCH 1/5] fuse: writepages: roll back changes if request not found Maxim Patlasov
2013-10-02 11:01 ` [PATCH 2/5] fuse: writepages: crop secondary requests on send Maxim Patlasov
2013-10-02 11:17 ` [PATCH 2/5] fuse: writepages: crop secondary requests on send -v2 Maxim Patlasov
2013-10-02 15:07 ` Miklos Szeredi
2013-10-02 15:46 ` Maxim Patlasov [this message]
2013-10-02 11:02 ` [PATCH 3/5] fuse: writepages: crop secondary requests on attach Maxim Patlasov
2013-10-02 11:02 ` [PATCH 4/5] fuse: writepage: update bdi writeout when deleting secondary request Maxim Patlasov
2013-10-02 11:03 ` [PATCH 5/5] fuse: writepages: protect secondary requests from fuse file release Maxim Patlasov
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=524C3FDF.5030201@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.