summary refs log tree commit diff
path: root/kernel
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2021-09-01 12:39:02 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2021-09-06 13:37:02 +0200
commit660585b56e63ca034ad506ea53c807c5cdca3196 (patch)
treea3ebc2af64f6e82c70ef1aaac95343b2ea443023 /kernel
parent59bda8ecee2ffc6a602b7bf2b9e43ca669cdbdcd (diff)
downloadlinux-660585b56e63ca034ad506ea53c807c5cdca3196.tar.gz
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: 2d82ab251ef0 ("virtiofs: propagate sync() to file server")
Cc: <stable@vger.kernel.org> # v5.14
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'kernel')
0 files changed, 0 insertions, 0 deletions