Commit graph

988,773 commits

Author SHA1 Message Date
Daniel Rosenberg
0f65460b10
UPSTREAM: ANDROID: bpf-fuse: Fix Setattr
Setattr implementation was mixing up some flags, and missing some of
them.

Test: atest android.appsecurity.cts.ExternalStorageHostTest
Bug: 202785178
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Id41fa30881766faad5858b658f5b6871c0ae46b3
2026-05-08 21:46:15 +02:00
Paul Lawrence
73ed3d189e
UPSTREAM: ANDROID: fuse-bpf: Support inotify
Test: fuse_test, atest CtsOsTestCases:android.os.cts.FileObserverTest
Bug: 202785178
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Signed-off-by: Alessio Balsini <balsini@google.com>
Change-Id: I88719a8ab23c2042fb8f50462f023e247aa4b6c3
2026-05-08 21:46:15 +02:00
Paul Lawrence
711aab4fc8
UPSTREAM: ANDROID: fuse-bpf: Make compile with CONFIG_FUSE but no CONFIG_FUSE_BPF
Fixes: ANDROID: fuse-bpf: Fix perms on readdir
Test: Builds with and without CONFIG_FUSE_BPF
Bug: 202785178
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: If8b4603dd6f4bd159bfd68fc61c377dcb62ebcd0
2026-05-08 21:46:14 +02:00
Paul Lawrence
f41257ce1b
UPSTREAM: ANDROID: fuse-bpf: Fix perms on readdir
Add checks for both fuse accesses and backing fs accesses

Bug: 202785178
Test: fuse_test passes, also atest ScopedStorageDeviceTest passes
Change-Id: Ida7d90e14ca36588a8cc19453e0d40b4f6f41aa9
Signed-off-by: Paul Lawrence <paullawrence@google.com>
2026-05-08 21:46:14 +02:00
Daniel Rosenberg
5f188dae20
UPSTREAM: ANDROID: fuse-bpf: Check if mkdir dentry setup
Uses lookup_one_len if given dentry is still negative/unlocked after
mkdir is called

Bug: 202785178
Test: atest android.scopedstorage.cts.device.ScopedStorageDeviceTest#testCreateAndDeleteEmptyDir
Change-Id: Id5c7dfd303c242d6966fab82d96712d289676857
Signed-off-by: Daniel Rosenberg <drosen@google.com>
2026-05-08 21:46:14 +02:00
Paul Lawrence
950ab97234
UPSTREAM: ANDROID: fuse-bpf: Close backing fds in fuse_dentry_revalidate
Bug: 202785178
Test: fuse_test runs, no leak on Android
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: If3c8dbe680f21c646e98f66140b842869c2c5abf
2026-05-08 21:46:14 +02:00
Paul Lawrence
f0e6d95711
UPSTREAM: ANDROID: fuse-bpf: Close backing-fd on both paths
Bug: 202785178
Test: fuse_test passes
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: Ie99e196cd67ab6d84a733cd3e027080ad2a4588b
2026-05-08 21:46:14 +02:00
Paul Lawrence
595da2719e
UPSTREAM: ANDROID: fuse-bpf: Partial fix for mmap'd files
This will simply pass all mapping operations to the backing file if it
exists. This is sufficient for our needs in Android13, but must be
extended in the future.

Signed-off-by: Paul Lawrence <paullawrence@google.com>
Bug: 202785178
Test: fuse_test passes
Change-Id: I3c51ef62415633ff0db039f25bfed1adf14e1e80
2026-05-08 21:46:14 +02:00
Daniel Rosenberg
b3fbcd3ca5
BACKPORT: ANDROID: fuse-bpf v1
Bug: 202785178
Test: test_fuse passes on linux, feature works on cuttlefish
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I987684b799b07391ccde350e98fde7976f5601aa
2026-05-08 21:46:14 +02:00
Daniel Rosenberg
2e6dc19099
BACKPORT: ANDROID: fuse: Move functions in preparation for fuse-bpf
Contains squash of this commit:

Author: Nathan Chancellor <nathan@kernel.org>
Date:   Fri Jan 20 09:40:12 2023 -0700

    ANDROID: fuse: Restore upstream type of bitfields in fuse_args

    Commit 88b7179fcdb59 ("ANDROID: fuse: Move functions in preparation for
    fuse-bpf") changed the type of these bitfields from the upstream type of
    'bool' to 'int', which causes several warnings with recent versions of
    clang:

        /builds/linux/fs/fuse/dir.c:168:19: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bi
t-bitfield-constant-conversion]
                args->out_argvar = true;
                                 ^ ~~~~
        /builds/linux/fs/fuse/dir.c:492:18: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bi
t-bitfield-constant-conversion]
                args.out_argvar = 1;
                                ^ ~
        /builds/linux/fs/fuse/dir.c:1649:20: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-b
it-bitfield-constant-conversion]
                ap.args.out_pages = true;
                                  ^ ~~~~
        /builds/linux/fs/fuse/dir.c:1650:21: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-b
it-bitfield-constant-conversion]
                ap.args.out_argvar = true;
                                   ^ ~~~~
        /builds/linux/fs/fuse/dir.c:1651:23: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-b
it-bitfield-constant-conversion]
                ap.args.page_zeroing = true;
                                     ^ ~~~~
        5 errors generated.
    When fuse_args was moved back to the internal implementation in commit
    9a5023967b4d2 ("ANDROID: fuse-bpf: Use fuse_bpf_args in uapi"), the type
    was not restored. Do so now to fix the warnings and reduce the delta
    with upstream.

    Bug: 265200230
    Change-Id: I4d51f331d842a1faff9a937140f0275130e70d73
    Signed-off-by: Nathan Chancellor <nathan@kernel.org>

Bug: 202785178
Test: test_fuse passes on linux, feature works on cuttlefish
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Ie738893a821d1f5f252c4c6e86274d55a6f09965
2026-05-08 21:46:14 +02:00
Amir Goldstein
26f1e21656
UPSTREAM: fuse: fix illegal access to inode with reused nodeid
commit 15db16837a35d8007cb8563358787412213db25e upstream.

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.

Stable backport notes:
* This is not a regression. The bug has been in fuse forever, but only
  a certain class of low level fuse filesystems can trigger this bug
* Because there is no way to check if this fix is applied in runtime,
  libfuse test_examples.py tests this fix with hardcoded check for
  kernel version >= 5.14
* After backport to stable kernel(s), the libfuse test can be updated
  to also check minimal stable kernel version(s)
* Depends on "fuse: fix bad inode" which is already applied to stable
  kernels v5.4.y and v5.10.y
* Required backporting helper inode_wrong_type()

Change-Id: I5f92158bc8ccdb50627fb035bb28d3ade51820b3
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-fsdevel/CAOQ4uxi8DymG=JO_sAU+wS8akFdzh+PuXwW3Ebgahd2Nwnh7zA@mail.gmail.com/
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:14 +02:00
Al Viro
831d8c1175
UPSTREAM: new helper: inode_wrong_type()
commit 6e3e2c4362e41a2f18e3f7a5ad81bd2f49a47b85 upstream.

inode_wrong_type(inode, mode) returns true if setting inode->i_mode
to given value would've changed the inode type.  We have enough of
those checks open-coded to make a helper worthwhile.

Change-Id: I346cb7a2d1cec2ca16096962d8adc9d7f848fc94
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:14 +02:00
Greg Kurz
462f12c6dc
UPSTREAM: fuse: Fix infinite loop in sget_fc()
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 ->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+
Change-Id: I709931fa4fc72c0a72707eae03b1de93a630ddf6
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:14 +02:00
Greg Kurz
e673499688
UPSTREAM: fuse: Fix crash if superblock of submount gets killed early
commit e3a43f2a95393000778f8f302d48795add2fc4a8 upstream.

As soon as fuse_dentry_automount() does up_write(&sb->s_umount), the
superblock can theoretically be killed. If this happens before the
submount was added to the &fc->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->s_umount to fix the inconsistency.
It is okay to nest fc->killsb under sb->s_umount, we already do this
on the ->kill_sb() path.

Change-Id: I5fb3786f86b7a7f1492f557284dd05d67bc8dce0
Signed-off-by: Greg Kurz <groug@kaod.org>
Fixes: bf109c64040f ("fuse: implement crossmounts")
Cc: stable@vger.kernel.org # v5.10+
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:14 +02:00
Greg Kurz
bc9748cb2a
UPSTREAM: fuse: Fix crash in fuse_dentry_automount() error path
commit d92d88f0568e97c437eeb79d9c9609bd8277406f upstream.

If fuse_fill_super_submount() returns an error, the error path
triggers a crash:

[   26.206673] BUG: kernel NULL pointer dereference, address: 0000000000000000
[...]
[   26.226362] RIP: 0010:__list_del_entry_valid+0x25/0x90
[...]
[   26.247938] Call Trace:
[   26.248300]  fuse_mount_remove+0x2c/0x70 [fuse]
[   26.248892]  virtio_kill_sb+0x22/0x160 [virtiofs]
[   26.249487]  deactivate_locked_super+0x36/0xa0
[   26.250077]  fuse_dentry_automount+0x178/0x1a0 [fuse]

The crash happens because fuse_mount_remove() assumes that the FUSE
mount was already added to list under the FUSE connection, but this
only done after fuse_fill_super_submount() has returned success.

This means that until fuse_fill_super_submount() has returned success,
the FUSE mount isn't actually owned by the superblock. We should thus
reclaim ownership by clearing sb->s_fs_info, which will skip the call
to fuse_mount_remove(), and perform rollback, like virtio_fs_get_tree()
already does for the root sb.

Fixes: bf109c64040f ("fuse: implement crossmounts")
Cc: stable@vger.kernel.org # v5.10+
Change-Id: Ie395b453a703cf3f1dda2c825c7de0fe4bd62d04
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:14 +02:00
Miklos Szeredi
3d04982cea
UPSTREAM: virtiofs: fix userns
[ Upstream commit 0a7419c68a45d2d066b996be5087aa2d07ce80eb ]

get_user_ns() is done twice (once in virtio_fs_get_tree() and once in
fuse_conn_init()), resulting in a reference leak.

Also looks better to use fsc->user_ns (which *should* be the
current_user_ns() at this point).

Change-Id: If41a5cefac82bc65e880ad14ed90f1adca9271ae
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-05-08 21:46:14 +02:00
Vivek Goyal
b9bba860d2
UPSTREAM: fuse: invalidate attrs when page writeback completes
[ Upstream commit 3466958beb31a8e9d3a1441a34228ed088b84f3e ]

In fuse when a direct/write-through write happens we invalidate attrs
because that might have updated mtime/ctime on server and cached
mtime/ctime will be stale.

What about page writeback path.  Looks like we don't invalidate attrs
there.  To be consistent, invalidate attrs in writeback path as well.  Only
exception is when writeback_cache is enabled.  In that case we strust local
mtime/ctime and there is no need to invalidate attrs.

Recently users started experiencing failure of xfstests generic/080,
geneirc/215 and generic/614 on virtiofs.  This happened only newer "stat"
utility and not older one.  This patch fixes the issue.

So what's the root cause of the issue.  Here is detailed explanation.

generic/080 test does mmap write to a file, closes the file and then checks
if mtime has been updated or not.  When file is closed, it leads to
flushing of dirty pages (and that should update mtime/ctime on server).
But we did not explicitly invalidate attrs after writeback finished.  Still
generic/080 passed so far and reason being that we invalidated atime in
fuse_readpages_end().  This is called in fuse_readahead() path and always
seems to trigger before mmaped write.

So after mmaped write when lstat() is called, it sees that atleast one of
the fields being asked for is invalid (atime) and that results in
generating GETATTR to server and mtime/ctime also get updated and test
passes.

But newer /usr/bin/stat seems to have moved to using statx() syscall now
(instead of using lstat()).  And statx() allows it to query only ctime or
mtime (and not rest of the basic stat fields).  That means when querying
for mtime, fuse_update_get_attr() sees that mtime is not invalid (only
atime is invalid).  So it does not generate a new GETATTR and fill stat
with cached mtime/ctime.  And that means updated mtime is not seen by
xfstest and tests start failing.

Invalidating attrs after writeback completion should solve this problem in
a generic manner.

Change-Id: I867c795d35306e17445d5e849676b31b2103c762
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-05-08 21:46:13 +02:00
Minchan Kim
6d89a44a1c
BACKPORT: ANDROID: mm: page_pinner: use put_user_page at fuse_copy_finish
fuse could use get_user_pages_fast by iov_iter_get_pages at
fuse_copy_fill so close the false positive by attributing
it by put_user_page.

Page pinned via pid 670, ts 4554195916 ns
PFN 83125 Block 162 type Movable Flags 0xfffffc008001e(referenced|uptodate|dirty|lru|swapbacked)
 try_grab_compound_head+0x1e8/0x240
 internal_get_user_pages_fast+0x66d/0xca0
 iov_iter_get_pages+0xd4/0x3a0
 fuse_copy_fill+0x197/0x200
 fuse_copy_one+0x6e/0xf0
 fuse_dev_do_read.constprop.0+0x435/0x7e0
 fuse_dev_read+0x5d/0x90
 new_sync_read+0x115/0x1a0
 vfs_read+0xf4/0x180
 ksys_read+0x5f/0xe0
 do_syscall_64+0x33/0x80
 entry_SYSCALL_64_after_hwframe+0x44/0xae

Re-name put_user_page -> put_page

Bug: 183414571
Signed-off-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Minchan Kim <minchan@google.com>
Change-Id: Idc80d4a34b546f25e8f6dbc68313d39586e914d9
2026-05-08 21:46:13 +02:00
Vivek Goyal
35036fca04
UPSTREAM: virtiofs: Fail dax mount if device does not support it
[ Upstream commit 3f9b9efd82a84f27e95d0414f852caf1fa839e83 ]

Right now "mount -t virtiofs -o dax myfs /mnt/virtiofs" succeeds even
if filesystem deivce does not have a cache window and hence DAX can't
be supported.

This gives a false sense to user that they are using DAX with virtiofs
but fact of the matter is that they are not.

Fix this by returning error if dax can't be supported and user has asked
for it.

Change-Id: Ibbf05e0c354ae47b6fd897f454d0712b202e0a34
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-05-08 21:46:13 +02:00
Miklos Szeredi
507c24a3c3
UPSTREAM: virtiofs fix leak in setup
[ Upstream commit 66ab33bf6d4341574f88b511e856a73f6f2a921e ]

This can be triggered for example by adding the "-omand" mount option,
which will be rejected and virtio_fs_fill_super() will return an error.

In such a case the allocations for fuse_conn and fuse_mount will leak due
to s_root not yet being set and so ->put_super() not being called.

Fixes: a62a8ef9d9 ("virtio-fs: add virtiofs filesystem")
Change-Id: I1a25fd72aaf8348e8bd1ca29b59df712d789e3f7
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-05-08 21:46:13 +02:00
Vivek Goyal
0da478369b
UPSTREAM: virtiofs: calculate number of scatter-gather elements accurately
virtiofs currently maps various buffers in scatter gather list and it looks
at number of pages (ap->pages) and assumes that same number of pages will
be used both for input and output (sg_count_fuse_req()), and calculates
total number of scatterlist elements accordingly.

But looks like this assumption is not valid in all the cases. For example,
Cai Qian reported that trinity, triggers warning with virtiofs sometimes.
A closer look revealed that if one calls ioctl(fd, 0x5a004000, buf), it
will trigger following warning.

WARN_ON(out_sgs + in_sgs != total_sgs)

In this case, total_sgs = 8, out_sgs=4, in_sgs=3. Number of pages is 2
(ap->pages), but out_sgs are using both the pages but in_sgs are using
only one page. In this case, fuse_do_ioctl() sets different size values
for input and output.

args->in_args[args->in_numargs - 1].size == 6656
args->out_args[args->out_numargs - 1].size == 4096

So current method of calculating how many scatter-gather list elements
will be used is not accurate. Make calculations more precise by parsing
size and ap->descs.

Reported-by: Qian Cai <cai@redhat.com>
Change-Id: I1ccdbce4b946a016a4a8faea234de0cb470825ac
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Link: https://lore.kernel.org/linux-fsdevel/5ea77e9f6cb8c2db43b09fbd4158ab2d8c066a0a.camel@redhat.com/
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Miklos Szeredi
5d30dbe4bf
UPSTREAM: fuse: connection remove fix
Re-add lost removal of fc from fuse_conn_list and the control filesystem.

Reported-by: kernel test robot <rong.a.chen@intel.com>
Fixes: fcee216beb9c ("fuse: split fuse_mount off of fuse_conn")
Change-Id: Icaaee7958947461b80a10d42a38ff5a3078e268a
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Max Reitz
8baaccc83c
UPSTREAM: fuse: implement crossmounts
FUSE servers can indicate crossmount points by setting FUSE_ATTR_SUBMOUNT
in fuse_attr.flags.  The inode will then be marked as S_AUTOMOUNT, and the
.d_automount implementation creates a new submount at that location, so
that the submount gets a distinct st_dev value.

Note that all submounts get a distinct superblock and a distinct st_dev
value, so for virtio-fs, even if the same filesystem is mounted more than
once on the host, none of its mount points will have the same st_dev.  We
need distinct superblocks because the superblock points to the root node,
but the different host mounts may show different trees (e.g. due to
submounts in some of them, but not in others).

Right now, this behavior is only enabled when fuse_conn.auto_submounts is
set, which is the case only for virtio-fs.

Change-Id: I455ddae7b02f28968cf78018b771d0c12d03bacd
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Christoph Hellwig
699354537f
BACKPORT: bdi: initialize ->ra_pages and ->io_pages in bdi_init
Set up a readahead size by default, as very few users have a good
reason to change it.  This means code, ecryptfs, and orangefs now
set up the values while they were previously missing it, while ubifs,
mtd and vboxsf manually set it to 0 to avoid readahead.

Change-Id: I2394fea47e8685f26aee9cc52c72018cd2715741
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: David Sterba <dsterba@suse.com> [btrfs]
Acked-by: Richard Weinberger <richard@nod.at> [ubifs, mtd]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2026-05-08 21:46:13 +02:00
Max Reitz
0774f61134
UPSTREAM: fuse: Allow fuse_fill_super_common() for submounts
Submounts have their own superblock, which needs to be initialized.
However, they do not have a fuse_fs_context associated with them, and
the root node's attributes should be taken from the mountpoint's node.

Extend fuse_fill_super_common() to work for submounts by making the @ctx
parameter optional, and by adding a @submount_finode parameter.

(There is a plain "unsigned" in an existing code block that is being
indented by this commit.  Extend it to "unsigned int" so checkpatch does
not complain.)

Change-Id: Ia20a19e84cdc80eb05d8ab8cd7e76da866363e44
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Max Reitz
5d830cf84d
BACKPORT: fuse: split fuse_mount off of fuse_conn
We want to allow submounts for the same fuse_conn, but with different
superblocks so that each of the submounts has its own device ID.  To do
so, we need to split all mount-specific information off of fuse_conn
into a new fuse_mount structure, so that multiple mounts can share a
single fuse_conn.

We need to take care only to perform connection-level actions once (i.e.
when the fuse_conn and thus the first fuse_mount are established, or
when the last fuse_mount and thus the fuse_conn are destroyed).  For
example, fuse_sb_destroy() must invoke fuse_send_destroy() until the
last superblock is released.

To do so, we keep track of which fuse_mount is the root mount and
perform all fuse_conn-level actions only when this fuse_mount is
involved.

Fixed the code for lots of 5.xx to 4.19 backports that google had
previously applied without this commit.

Change-Id: I4169dac1eb30b96c5f43ecadd339746be16f77fc
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Max Reitz
2eff56e2dd
UPSTREAM: fuse: drop fuse_conn parameter where possible
With the last commit, all functions that handle some existing fuse_req
no longer need to be given the associated fuse_conn, because they can
get it from the fuse_req object.

Change-Id: I0436ff160047ca7bc1de46681cd4f9e92878561f
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Alistair Delva
5d4da27005
ANDROID: GKI: Don't compact fuse_req when CONFIG_VIRTIO_FS=n
Otherwise we cannot enable VIRTIO_FS downstream.

Bug: 161843089
Change-Id: I317b8c425ab96a1bd484b85b41ce3cb036327117
Signed-off-by: Alistair Delva <adelva@google.com>
2026-05-08 21:46:13 +02:00
Max Reitz
9784782e98
UPSTREAM: fuse: store fuse_conn in fuse_req
Every fuse_req belongs to a fuse_conn.  Right now, we always know which
fuse_conn that is based on the respective device, but we want to allow
multiple (sub)mounts per single connection, and then the corresponding
filesystem is not going to be so trivial to obtain.

Storing a pointer to the associated fuse_conn in every fuse_req will
allow us to trivially find any request's superblock (and thus
filesystem) even then.

Change-Id: I60a5e891535ab5c172d3658c3b6f42f4804e2a21
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Max Reitz
d67035009c
UPSTREAM: fuse: add submount support to <uapi/linux/fuse.h>
- Add fuse_attr.flags

- Add FUSE_ATTR_SUBMOUNT

  This is a flag for fuse_attr.flags that indicates that the given entry
  resides on a different filesystem than the parent, and as such should
  have a different st_dev.

- Add FUSE_SUBMOUNTS

  The client sets this flag if it supports automounting directories.

Change-Id: Ibea2d75d0a93dc3c269555fdb7d0ee58af7860b4
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:13 +02:00
Vivek Goyal
99d630bf58
UPSTREAM: virtiofs: add logic to free up a memory range
Add logic to free up a busy memory range. Freed memory range will be
returned to free pool. Add a worker which can be started to select
and free some busy memory ranges.

Process can also steal one of its busy dax ranges if free range is not
available. I will refer it to as direct reclaim.

If free range is not available and nothing can't be stolen from same
inode, caller waits on a waitq for free range to become available.

For reclaiming a range, as of now we need to hold following locks in
specified order.

	down_write(&fi->i_mmap_sem);
	down_write(&fi->dax->sem);

We look for a free range in following order.

A. Try to get a free range.
B. If not, try direct reclaim.
C. If not, wait for a memory range to become free

Change-Id: Idea3464f4c14faabce59fdd493c10f31b9dbd0ae
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
f5b74e7e64
UPSTREAM: virtiofs: maintain a list of busy elements
This list will be used selecting fuse_dax_mapping to free when number of
free mappings drops below a threshold.

Change-Id: I311dba8e084206ed4b983779674ee1b160d7a757
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
811ed4644f
virtiofs: serialize truncate/punch_hole and dax fault path
Currently in fuse we don't seem have any lock which can serialize fault
path with truncate/punch_hole path. With dax support I need one for
following reasons.

1. Dax requirement

  DAX fault code relies on inode size being stable for the duration of
  fault and want to serialize with truncate/punch_hole and they explicitly
  mention it.

  static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
                               const struct iomap_ops *ops)
        /*
         * Check whether offset isn't beyond end of file now. Caller is
         * supposed to hold locks serializing us with truncate / punch hole so
         * this is a reliable test.
         */
        max_pgoff = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);

2. Make sure there are no users of pages being truncated/punch_hole

  get_user_pages() might take references to page and then do some DMA
  to said pages. Filesystem might truncate those pages without knowing
  that a DMA is in progress or some I/O is in progress. So use
  dax_layout_busy_page() to make sure there are no such references
  and I/O is not in progress on said pages before moving ahead with
  truncation.

3. Limitation of kvm page fault error reporting

  If we are truncating file on host first and then removing mappings in
  guest lateter (truncate page cache etc), then this could lead to a
  problem with KVM. Say a mapping is in place in guest and truncation
  happens on host. Now if guest accesses that mapping, then host will
  take a fault and kvm will either exit to qemu or spin infinitely.

  IOW, before we do truncation on host, we need to make sure that guest
  inode does not have any mapping in that region or whole file.

4. virtiofs memory range reclaim

 Soon I will introduce the notion of being able to reclaim dax memory
 ranges from a fuse dax inode. There also I need to make sure that
 no I/O or fault is going on in the reclaimed range and nobody is using
 it so that range can be reclaimed without issues.

Currently if we take inode lock, that serializes read/write. But it does
not do anything for faults. So I add another semaphore fuse_inode->i_mmap_sem
for this purpose.  It can be used to serialize with faults.

As of now, I am adding taking this semaphore only in dax fault path and
not regular fault path because existing code does not have one. May
be existing code can benefit from it as well to take care of some
races, but that we can fix later if need be. For now, I am just focussing
only on DAX path which is new path.

Also added logic to take fuse_inode->i_mmap_sem in
truncate/punch_hole/open(O_TRUNC) path to make sure file truncation and
fuse dax fault are mutually exlusive and avoid all the above problems.

Change-Id: I156a034a6d2e70fb90372815dfb5f61f033b7cb8
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
58ba749543
UPSTREAM: virtiofs: define dax address space operations
This is done along the lines of ext4 and xfs.  I primarily wanted
->writepages hook at this time so that I could call into
dax_writeback_mapping_range().  This in turn will decide which pfns need to
be written back.

Change-Id: If7c2e595df71f433368a0a4a5a77eca6fcb7549d
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Stefan Hajnoczi
f0e895b3e9
UPSTREAM: virtiofs: add DAX mmap support
Add DAX mmap() support.

Change-Id: I80e46a9054db40ae56e797c070bf7ecc3c84e343
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
9fe4e93da2
UPSTREAM: virtiofs: implement dax read/write operations
This patch implements basic DAX support. mmap() is not implemented
yet and will come in later patches. This patch looks into implemeting
read/write.

We make use of interval tree to keep track of per inode dax mappings.

Do not use dax for file extending writes, instead just send WRITE message
to daemon (like we do for direct I/O path). This will keep write and
i_size change atomic w.r.t crash.

Change-Id: Ia135d8554026720dc87e4ef5858b230e91533de8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
Signed-off-by: Peng Tao <tao.peng@linux.alibaba.com>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
6672c1f145
UPSTREAM: virtiofs: introduce setupmapping/removemapping commands
Introduce two new fuse commands to setup/remove memory mappings. This
will be used to setup/tear down file mapping in dax window.

Change-Id: I9a5686146f83a72bdef0147bd1a96ec4dd1a278d
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Peng Tao <tao.peng@linux.alibaba.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Stefan Hajnoczi
12d56dffdc
UPSTREAM: virtiofs: implement FUSE_INIT map_alignment field
The device communicates FUSE_SETUPMAPPING/FUSE_REMOVMAPPING alignment
constraints via the FUST_INIT map_alignment field.  Parse this field and
ensure our DAX mappings meet the alignment constraints.

We don't actually align anything differently since our mappings are
already 2MB aligned.  Just check the value when the connection is
established.  If it becomes necessary to honor arbitrary alignments in
the future we'll have to adjust how mappings are sized.

The upshot of this commit is that we can be confident that mappings will
work even when emulating x86 on Power and similar combinations where the
host page sizes are different.

Change-Id: I8c7b002aa413dbdae43dc159d82cba672e671351
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
0c4fa1ea4c
UPSTREAM: virtiofs: keep a list of free dax memory ranges
Divide the dax memory range into fixed size ranges (2MB for now) and put
them in a list. This will track free ranges. Once an inode requires a
free range, we will take one from here and put it in interval-tree
of ranges assigned to inode.

Change-Id: Icb27b111f8e72d55aa0e12e679946e84af79a285
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Peng Tao <tao.peng@linux.alibaba.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Sebastien Boeuf
481a6af47b
UPSTREAM: virtio: Add get_shm_region method
Virtio defines 'shared memory regions' that provide a continuously
shared region between the host and guest.

Provide a method to find a particular region on a device.

Change-Id: I18f5c3b72fd83ab27bf346de3f24aeb61a9f4ab8
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
3161993224
UPSTREAM: dax, pmem: Add a dax operation zero_page_range
Add a dax operation zero_page_range, to zero a page. This will also clear any
known poison in the page being zeroed.

As of now, zeroing of one page is allowed in a single call. There
are no callers which are trying to zero more than a page in a single call.
Once we grow the callers which zero more than a page in single call, we
can add that support. Primary reason for not doing that yet is that this
will add little complexity in dm implementation where a range might be
spanning multiple underlying targets and one will have to split the range
into multiple sub ranges and call zero_page_range() on individual targets.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Change-Id: Id86c5bac0824101755c69eb8822760fd05007210
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Link: https://lore.kernel.org/r/20200228163456.1587-3-vgoyal@redhat.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2026-05-08 21:46:12 +02:00
Vivek Goyal
9f496602dd
UPSTREAM: pmem: Add functions for reading/writing page to/from pmem
This splits pmem_do_bvec() into pmem_do_read() and pmem_do_write().
pmem_do_write() will be used by pmem zero_page_range() as well. Hence
sharing the same code.

Change-Id: I5fe20ed0dd24028345b6cff111b79f829cba6fbf
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Link: https://lore.kernel.org/r/20200228163456.1587-2-vgoyal@redhat.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
2026-05-08 21:46:12 +02:00
André Almeida
6c16f6636e
UPSTREAM: fuse: update project homepage
As stated in https://sourceforge.net/projects/fuse/, "the FUSE project has
moved to https://github.com/libfuse/" in 22-Dec-2015. Update URLs to
reflect this.

Change-Id: Ic0e5f3ea47ea4a49ea0a2946ba9db6035f31c49f
Signed-off-by: André Almeida <andrealmeid@collabora.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Miklos Szeredi
01906dcb71
UPSTREAM: fuse: clean up condition for writepage sending
fuse_writepages_fill uses following construction:

if (wpa && ap->num_pages &&
    (A || B || C)) {
        action;
} else if (wpa && D) {
        if (E) {
                the same action;
        }
}

 - ap->num_pages check is always true and can be removed

 - "if" and "else if" calls the same action and can be merged.

Move checking A, B, C, D, E conditions to a helper, add comments.

Original-patch-by: Vasily Averin <vvs@virtuozzo.com>
Change-Id: Ibb9755ad4f025cf027b998205d6838727dad9c72
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:12 +02:00
Miklos Szeredi
abf9dfb0e1
UPSTREAM: fuse: reject options on reconfigure via fsconfig(2)
Previous patch changed handling of remount/reconfigure to ignore all
options, including those that are unknown to the fuse kernel fs.  This was
done for backward compatibility, but this likely only affects the old
mount(2) API.

The new fsconfig(2) based reconfiguration could possibly be improved.  This
would make the new API less of a drop in replacement for the old, OTOH this
is a good chance to get rid of some weirdnesses in the old API.

Several other behaviors might make sense:

 1) unknown options are rejected, known options are ignored

 2) unknown options are rejected, known options are rejected if the value
 is changed, allowed otherwise

 3) all options are rejected

Prior to the backward compatibility fix to ignore all options all known
options were accepted (1), even if they change the value of a mount
parameter; fuse_reconfigure() does not look at the config values set by
fuse_parse_param().

To fix that we'd need to verify that the value provided is the same as set
in the initial configuration (2).  The major drawback is that this is much
more complex than just rejecting all attempts at changing options (3);
i.e. all options signify initial configuration values and don't make sense
on reconfigure.

This patch opts for (3) with the rationale that no mount options are
reconfigurable in fuse.

Change-Id: I1eb25670fd437473a1a6c431fed1bb68a80c1046
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:11 +02:00
Miklos Szeredi
5cf159f2dd
UPSTREAM: fuse: fix warning in tree_insert() and clean up writepage insertion
fuse_writepages_fill() calls tree_insert() with ap->num_pages = 0 which
triggers the following warning:

 WARNING: CPU: 1 PID: 17211 at fs/fuse/file.c:1728 tree_insert+0xab/0xc0 [fuse]
 RIP: 0010:tree_insert+0xab/0xc0 [fuse]
 Call Trace:
  fuse_writepages_fill+0x5da/0x6a0 [fuse]
  write_cache_pages+0x171/0x470
  fuse_writepages+0x8a/0x100 [fuse]
  do_writepages+0x43/0xe0

Fix up the warning and clean up the code around rb-tree insertion:

 - Rename tree_insert() to fuse_insert_writeback() and make it return the
   conflicting entry in case of failure

 - Re-add tree_insert() as a wrapper around fuse_insert_writeback()

 - Rename fuse_writepage_in_flight() to fuse_writepage_add() and reverse
   the meaning of the return value to mean

    + "true" in case the writepage entry was successfully added

    + "false" in case it was in-fligt queued on an existing writepage
       entry's auxiliary list or the existing writepage entry's temporary
       page updated

   Switch from fuse_find_writeback() + tree_insert() to
   fuse_insert_writeback()

 - Move setting orig_pages to before inserting/updating the entry; this may
   result in the orig_pages value being discarded later in case of an
   in-flight request

 - In case of a new writepage entry use fuse_writepage_add()
   unconditionally, only set data->wpa if the entry was added.

Fixes: 6b2fb79963fb ("fuse: optimize writepages search")
Reported-by: kernel test robot <rong.a.chen@intel.com>
Original-path-by: Vasily Averin <vvs@virtuozzo.com>
Change-Id: I837fe9290f1e026e90175f4bbd3ff831b85c5e46
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:11 +02:00
Miklos Szeredi
232516a946
UPSTREAM: fuse: move rb_erase() before tree_insert()
In fuse_writepage_end() the old writepages entry needs to be removed from
the rbtree before inserting the new one, otherwise tree_insert() would
fail.  This is a very rare codepath and no reproducer exists.

Change-Id: Ifd7bb409f2e23e12054a2681920f9dc3ccc96930
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:11 +02:00
Maxim Patlasov
cd15da23c6
UPSTREAM: fuse: optimize writepages search
Re-work fi->writepages, replacing list with rb-tree.  This improves
performance because kernel fuse iterates through fi->writepages for each
writeback page and typical number of entries is about 800 (for 100MB of
fuse writeback).

Before patch:

10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 41.3473 s, 260 MB/s

 2  1      0 57445400  40416 6323676    0    0    33 374743 8633 19210  1  8 88  3  0

  29.86%  [kernel]               [k] _raw_spin_lock
  26.62%  [fuse]                 [k] fuse_page_is_writeback

After patch:

10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 21.4954 s, 500 MB/s

 2  9      0 53676040  31744 10265984    0    0    64 854790 10956 48387  1  6 88  6  0

  23.55%  [kernel]             [k] copy_user_enhanced_fast_string
   9.87%  [kernel]             [k] __memcpy
   3.10%  [kernel]             [k] _raw_spin_lock

Change-Id: I381c5356f90332181f427de0feeddf9fcfc08f83
Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com>
Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:11 +02:00
Miklos Szeredi
e86391af09
UPSTREAM: fuse: use dump_page
Instead of custom page dumping, use the standard helper.

Reported-by: Matthew Wilcox <willy@infradead.org>
Change-Id: Ia4cb115a3265ad613b66c5c953f2bf917a0b270f
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:11 +02:00
Miklos Szeredi
48e94fe1d2
UPSTREAM: fuse: always allow query of st_dev
Fuse mounts without "allow_other" are off-limits to all non-owners.  Yet it
makes sense to allow querying st_dev on the root, since this value is
provided by the kernel, not the userspace filesystem.

Allow statx(2) with a zero request mask to succeed on a fuse mounts for all
users.

Reported-by: Nikolaus Rath <Nikolaus@rath.org>
Change-Id: Ie7215acbfa5ee7cbfe512b3e12a00d1045f8fbc3
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2026-05-08 21:46:11 +02:00