]> git.baikalelectronics.ru Git - kernel.git/commit
fuse: wait for writepages in syncfs
authorMiklos Szeredi <mszeredi@redhat.com>
Wed, 1 Sep 2021 10:39:02 +0000 (12:39 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 6 Sep 2021 11:37:02 +0000 (13:37 +0200)
commit8d80ebb0387844a4cff7116fe338f168598c59ed
treea3ebc2af64f6e82c70ef1aaac95343b2ea443023
parent23368fc191f334fd0e72e9d831acfa7d3675ccb8
fuse: wait for writepages in syncfs

In case of fuse the MM subsystem doesn't guarantee that page writeback
completes by the time ->sync_fs() is called.  This is because fuse
completes page writeback immediately to prevent DoS of memory reclaim by
the userspace file server.

This means that fuse itself must ensure that writes are synced before
sending the SYNCFS request to the server.

Introduce sync buckets, that hold a counter for the number of outstanding
write requests.  On syncfs replace the current bucket with a new one and
wait until the old bucket's counter goes down to zero.

It is possible to have multiple syncfs calls in parallel, in which case
there could be more than one waited-on buckets.  Descendant buckets must
not complete until the parent completes.  Add a count to the child (new)
bucket until the (parent) old bucket completes.

Use RCU protection to dereference the current bucket and to wake up an
emptied bucket.  Use fc->lock to protect against parallel assignments to
the current bucket.

This leaves just the counter to be a possible scalability issue.  The
fc->num_waiting counter has a similar issue, so both should be addressed at
the same time.

Reported-by: Amir Goldstein <amir73il@gmail.com>
Fixes: 5b9f7c66a9f3 ("virtiofs: propagate sync() to file server")
Cc: <stable@vger.kernel.org> # v5.14
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c