<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/git/stable/linux.git/fs/fuse, branch linux-5.13.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<id>https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-5.13.y</id>
<link rel='self' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-5.13.y'/>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/'/>
<updated>2021-09-15T08:00:58+00:00</updated>
<entry>
<title>fuse: wait for writepages in syncfs</title>
<updated>2021-09-15T08:00:58+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@redhat.com</email>
</author>
<published>2021-09-01T10:39:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=10c6ecc470fc109e515de1f4cc55cec435d3cac8'/>
<id>urn:sha1:10c6ecc470fc109e515de1f4cc55cec435d3cac8</id>
<content type='text'>
commit 660585b56e63ca034ad506ea53c807c5cdca3196 upstream.

In case of fuse the MM subsystem doesn't guarantee that page writeback
completes by the time -&gt;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-&gt;lock to protect against parallel assignments to
the current bucket.

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

Reported-by: Amir Goldstein &lt;amir73il@gmail.com&gt;
Fixes: 2d82ab251ef0 ("virtiofs: propagate sync() to file server")
Cc: &lt;stable@vger.kernel.org&gt; # v5.14
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fuse: flush extending writes</title>
<updated>2021-09-15T08:00:58+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@redhat.com</email>
</author>
<published>2021-08-31T12:18:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=8d573aa25ffba5f058cd0fcc54040662626b353e'/>
<id>urn:sha1:8d573aa25ffba5f058cd0fcc54040662626b353e</id>
<content type='text'>
commit 59bda8ecee2ffc6a602b7bf2b9e43ca669cdbdcd upstream.

Callers of fuse_writeback_range() assume that the file is ready for
modification by the server in the supplied byte range after the call
returns.

If there's a write that extends the file beyond the end of the supplied
range, then the file needs to be extended to at least the end of the range,
but currently that's not done.

There are at least two cases where this can cause problems:

 - copy_file_range() will return short count if the file is not extended
   up to end of the source range.

 - FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE will not extend the file,
   hence the region may not be fully allocated.

Fix by flushing writes from the start of the range up to the end of the
file.  This could be optimized if the writes are non-extending, etc, but
it's probably not worth the trouble.

Fixes: a2bc92362941 ("fuse: fix copy_file_range() in the writeback case")
Fixes: 6b1bdb56b17c ("fuse: allow fallocate(FALLOC_FL_ZERO_RANGE)")
Cc: &lt;stable@vger.kernel.org&gt;  # v5.2
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fuse: truncate pagecache on atomic_o_trunc</title>
<updated>2021-09-15T08:00:58+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@redhat.com</email>
</author>
<published>2021-08-17T19:05:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=588309f1c89d09d3a85758d37d07961f71c43f60'/>
<id>urn:sha1:588309f1c89d09d3a85758d37d07961f71c43f60</id>
<content type='text'>
commit 76224355db7570cbe6b6f75c8929a1558828dd55 upstream.

fuse_finish_open() will be called with FUSE_NOWRITE in case of atomic
O_TRUNC.  This can deadlock with fuse_wait_on_page_writeback() in
fuse_launder_page() triggered by invalidate_inode_pages2().

Fix by replacing invalidate_inode_pages2() in fuse_finish_open() with a
truncate_pagecache() call.  This makes sense regardless of FOPEN_KEEP_CACHE
or fc-&gt;writeback cache, so do it unconditionally.

Reported-by: Xie Yongji &lt;xieyongji@bytedance.com&gt;
Reported-and-tested-by: syzbot+bea44a5189836d956894@syzkaller.appspotmail.com
Fixes: e4648309b85a ("fuse: truncate pending writes on O_TRUNC")
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>fuse: fix illegal access to inode with reused nodeid</title>
<updated>2021-07-20T14:00:24+00:00</updated>
<author>
<name>Amir Goldstein</name>
<email>amir73il@gmail.com</email>
</author>
<published>2021-06-21T11:03:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=c09a4ad6251f9354df0915ac5b8f22c7b9d6bc11'/>
<id>urn:sha1:c09a4ad6251f9354df0915ac5b8f22c7b9d6bc11</id>
<content type='text'>
[ Upstream commit 15db16837a35d8007cb8563358787412213db25e ]

Server responds to LOOKUP and other ops (READDIRPLUS/CREATE/MKNOD/...)
with ourarg containing nodeid and generation.

If a fuse inode is found in inode cache with the same nodeid but different
generation, the existing fuse inode should be unhashed and marked "bad" and
a new inode with the new generation should be hashed instead.

This can happen, for example, with passhrough fuse filesystem that returns
the real filesystem ino/generation on lookup and where real inode numbers
can get recycled due to real files being unlinked not via the fuse
passthrough filesystem.

With current code, this situation will not be detected and an old fuse
dentry that used to point to an older generation real inode, can be used to
access a completely new inode, which should be accessed only via the new
dentry.

Note that because the FORGET message carries the nodeid w/o generation, the
server should wait to get FORGET counts for the nlookup counts of the old
and reused inodes combined, before it can free the resources associated to
that nodeid.

Signed-off-by: Amir Goldstein &lt;amir73il@gmail.com&gt;
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>virtiofs: propagate sync() to file server</title>
<updated>2021-07-20T14:00:24+00:00</updated>
<author>
<name>Greg Kurz</name>
<email>groug@kaod.org</email>
</author>
<published>2021-05-20T15:46:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6ba041fc3c441e0cf4762f4baf0166e8d34f6802'/>
<id>urn:sha1:6ba041fc3c441e0cf4762f4baf0166e8d34f6802</id>
<content type='text'>
[ Upstream commit 2d82ab251ef0f6e7716279b04e9b5a01a86ca530 ]

Even if POSIX doesn't mandate it, linux users legitimately expect sync() to
flush all data and metadata to physical storage when it is located on the
same system.  This isn't happening with virtiofs though: sync() inside the
guest returns right away even though data still needs to be flushed from
the host page cache.

This is easily demonstrated by doing the following in the guest:

$ dd if=/dev/zero of=/mnt/foo bs=1M count=5K ; strace -T -e sync sync
5120+0 records in
5120+0 records out
5368709120 bytes (5.4 GB, 5.0 GiB) copied, 5.22224 s, 1.0 GB/s
sync()                                  = 0 &lt;0.024068&gt;

and start the following in the host when the 'dd' command completes
in the guest:

$ strace -T -e fsync /usr/bin/sync virtiofs/foo
fsync(3)                                = 0 &lt;10.371640&gt;

There are no good reasons not to honor the expected behavior of sync()
actually: it gives an unrealistic impression that virtiofs is super fast
and that data has safely landed on HW, which isn't the case obviously.

Implement a -&gt;sync_fs() superblock operation that sends a new FUSE_SYNCFS
request type for this purpose.  Provision a 64-bit placeholder for possible
future extensions.  Since the file server cannot handle the wait == 0 case,
we skip it to avoid a gratuitous roundtrip.  Note that this is
per-superblock: a FUSE_SYNCFS is send for the root mount and for each
submount.

Like with FUSE_FSYNC and FUSE_FSYNCDIR, lack of support for FUSE_SYNCFS in
the file server is treated as permanent success.  This ensures
compatibility with older file servers: the client will get the current
behavior of sync() not being propagated to the file server.

Note that such an operation allows the file server to DoS sync().  Since a
typical FUSE file server is an untrusted piece of software running in
userspace, this is disabled by default.  Only enable it with virtiofs for
now since virtiofsd is supposedly trusted by the guest kernel.

Reported-by: Robert Krawitz &lt;rlk@redhat.com&gt;
Signed-off-by: Greg Kurz &lt;groug@kaod.org&gt;
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>fuse: reject internal errno</title>
<updated>2021-07-14T15:06:18+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@redhat.com</email>
</author>
<published>2021-06-22T07:15:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=0c1678f223daf89364283d4fa1b362b404d7b056'/>
<id>urn:sha1:0c1678f223daf89364283d4fa1b362b404d7b056</id>
<content type='text'>
commit 49221cf86d18bb66fe95d3338cb33bd4b9880ca5 upstream.

Don't allow userspace to report errors that could be kernel-internal.

Reported-by: Anatoly Trosinenko &lt;anatoly.trosinenko@gmail.com&gt;
Fixes: 334f485df85a ("[PATCH] FUSE - device functions")
Cc: &lt;stable@vger.kernel.org&gt; # v2.6.14
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>fuse: check connected before queueing on fpq-&gt;io</title>
<updated>2021-07-14T15:06:18+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@redhat.com</email>
</author>
<published>2021-06-22T07:15:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2644fd6588e5951012cd4fc7fe016ea8c7157eff'/>
<id>urn:sha1:2644fd6588e5951012cd4fc7fe016ea8c7157eff</id>
<content type='text'>
commit 80ef08670d4c28a06a3de954bd350368780bcfef upstream.

A request could end up on the fpq-&gt;io list after fuse_abort_conn() has
reset fpq-&gt;connected and aborted requests on that list:

Thread-1			  Thread-2
========			  ========
-&gt;fuse_simple_request()           -&gt;shutdown
  -&gt;__fuse_request_send()
    -&gt;queue_request()		-&gt;fuse_abort_conn()
-&gt;fuse_dev_do_read()                -&gt;acquire(fpq-&gt;lock)
  -&gt;wait_for(fpq-&gt;lock) 	  -&gt;set err to all req's in fpq-&gt;io
				  -&gt;release(fpq-&gt;lock)
  -&gt;acquire(fpq-&gt;lock)
  -&gt;add req to fpq-&gt;io

After the userspace copy is done the request will be ended, but
req-&gt;out.h.error will remain uninitialized.  Also the copy might block
despite being already aborted.

Fix both issues by not allowing the request to be queued on the fpq-&gt;io
list after fuse_abort_conn() has processed this list.

Reported-by: Pradeep P V K &lt;pragalla@codeaurora.org&gt;
Fixes: fd22d62ed0c3 ("fuse: no fc-&gt;lock for iqueue parts")
Cc: &lt;stable@vger.kernel.org&gt; # v4.2
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>fuse: ignore PG_workingset after stealing</title>
<updated>2021-07-14T15:06:18+00:00</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@redhat.com</email>
</author>
<published>2021-06-18T19:16:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=76d97f2f3b028974f681f32884780f45e09d0d56'/>
<id>urn:sha1:76d97f2f3b028974f681f32884780f45e09d0d56</id>
<content type='text'>
commit b89ecd60d38ec042d63bdb376c722a16f92bcb88 upstream.

Fix the "fuse: trying to steal weird page" warning.

Description from Johannes Weiner:

  "Think of it as similar to PG_active. It's just another usage/heat
   indicator of file and anon pages on the reclaim LRU that, unlike
   PG_active, persists across deactivation and even reclaim (we store it in
   the page cache / swapper cache tree until the page refaults).

   So if fuse accepts pages that can legally have PG_active set,
   PG_workingset is fine too."

Reported-by: Thomas Lindroth &lt;thomas.lindroth@gmail.com&gt;
Fixes: 1899ad18c607 ("mm: workingset: tell cache transitions from workingset thrashing")
Cc: &lt;stable@vger.kernel.org&gt; # v4.20
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>fuse: Fix infinite loop in sget_fc()</title>
<updated>2021-07-14T15:06:18+00:00</updated>
<author>
<name>Greg Kurz</name>
<email>groug@kaod.org</email>
</author>
<published>2021-06-04T16:11:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=108adb1a56680e47119d94ae3c1beeae1e5ea9a0'/>
<id>urn:sha1:108adb1a56680e47119d94ae3c1beeae1e5ea9a0</id>
<content type='text'>
commit e4a9ccdd1c03b3dc58214874399d24331ea0a3ab upstream.

We don't set the SB_BORN flag on submounts. This is wrong as these
superblocks are then considered as partially constructed or dying
in the rest of the code and can break some assumptions.

One such case is when you have a virtiofs filesystem with submounts
and you try to mount it again : virtio_fs_get_tree() tries to obtain
a superblock with sget_fc(). The logic in sget_fc() is to loop until
it has either found an existing matching superblock with SB_BORN set
or to create a brand new one. It is assumed that a superblock without
SB_BORN is transient and the loop is restarted. Forgetting to set
SB_BORN on submounts hence causes sget_fc() to retry forever.

Setting SB_BORN requires special care, i.e. a write barrier for
super_cache_count() which can check SB_BORN without taking any lock.
We should call vfs_get_tree() to deal with that but this requires
to have a proper -&gt;get_tree() implementation for submounts, which
is a bigger piece of work. Go for a simple bug fix in the meatime.

Fixes: bf109c64040f ("fuse: implement crossmounts")
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Greg Kurz &lt;groug@kaod.org&gt;
Reviewed-by: Max Reitz &lt;mreitz@redhat.com&gt;
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>fuse: Fix crash if superblock of submount gets killed early</title>
<updated>2021-07-14T15:06:18+00:00</updated>
<author>
<name>Greg Kurz</name>
<email>groug@kaod.org</email>
</author>
<published>2021-06-04T16:11:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=809b077db6b821c17b317da46ce10f7df036adfe'/>
<id>urn:sha1:809b077db6b821c17b317da46ce10f7df036adfe</id>
<content type='text'>
commit e3a43f2a95393000778f8f302d48795add2fc4a8 upstream.

As soon as fuse_dentry_automount() does up_write(&amp;sb-&gt;s_umount), the
superblock can theoretically be killed. If this happens before the
submount was added to the &amp;fc-&gt;mounts list, fuse_mount_remove() later
crashes in list_del_init() because it assumes the submount to be
already there.

Add the submount before dropping sb-&gt;s_umount to fix the inconsistency.
It is okay to nest fc-&gt;killsb under sb-&gt;s_umount, we already do this
on the -&gt;kill_sb() path.

Signed-off-by: Greg Kurz &lt;groug@kaod.org&gt;
Fixes: bf109c64040f ("fuse: implement crossmounts")
Cc: stable@vger.kernel.org # v5.10+
Reviewed-by: Max Reitz &lt;mreitz@redhat.com&gt;
Signed-off-by: Miklos Szeredi &lt;mszeredi@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
</feed>
