Commit graph

982,036 commits

Author SHA1 Message Date
Paul Lawrence
aeeb2c9cb3
UPSTREAM: ANDROID: fuse-bpf: Follow mounts in lookups
Bug: 292925770
Test: fuse_test run. The following steps on Android also now pass:

	Create /data/123 and /data/media/0/Android/data/45 directories
	Mount /data/123 directory to /data/media/0/Android/data/45 directory
	Create 1.txt under the /data/123 directory

	File 1.txt should appear in /storage/emulated/0/Android/data/45
Signed-off-by: Paul Lawrence <paullawrence@google.com>
(cherry picked from https://android-review.googlesource.com/q/commit:9323938705b42cb4dd863d5cf8022ba8f2282952)
Merged-In: I1fe27d743ca2981e624a9aa87d9ab6deb313aadc
Change-Id: I1fe27d743ca2981e624a9aa87d9ab6deb313aadc
2026-05-08 21:46:19 +02:00
Hangyu Hua
2068b53c6a
UPSTREAM: fuse: dax: set fc->dax to NULL in fuse_dax_conn_free()
commit 7f8ed28d1401320bcb02dda81b3c23ab2dc5a6d8 upstream.

fuse_dax_conn_free() will be called when fuse_fill_super_common() fails
after fuse_dax_conn_alloc(). Then deactivate_locked_super() in
virtio_fs_get_tree() will call virtio_kill_sb() to release the discarded
superblock. This will call fuse_dax_conn_free() again in fuse_conn_put(),
resulting in a possible double free.

Fixes: 1dd539577c42 ("virtiofs: add a mount option to enable dax")
Change-Id: I5aabc81ad4f96078c612f2ec1c9077f21f4ffae4
Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Cc: <stable@vger.kernel.org> # v5.10
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:19 +02:00
Paul Lawrence
fa625f8622
BACKPORT: ANDROID: fuse-bpf: Ignore readaheads unless they go to the daemon
readpages will be triggered on the fuse fs in passthrough mode though
system calls like fadvise. If the daemon isn't aware of the file, this
will likely cause a hang.

For the moment, simply ignore fadvise in this situation

Bug: 301201239
Test: fuse_test, atest ScopedStorageDeviceTest both pass
Signed-off-by: Paul Lawrence <paullawrence@google.com>
(cherry picked from https://android-review.googlesource.com/q/commit:ac9071df3ba6715219a16a44d4711f041b0c25de)
Merged-In: I524a84aeeb1b1593e51264fcc37f7cfa66757168
Change-Id: I524a84aeeb1b1593e51264fcc37f7cfa66757168
2026-05-08 21:46:19 +02:00
liujing40
3ab55eae01
UPSTREAM: ANDROID: fuse-bpf: Add NULL pointer check in fuse_release_in
If open request sent to classic fuse, backing_file is null.
In fuse_release_initialize, fput will trigger a crash.

Bug: 297831741
Signed-off-by: liujing40 <liujing40@xiaomi.corp-partner.google.com>
(cherry picked from https://android-review.googlesource.com/q/commit:4d2ff573981f06ba09e1ddda8726bb73ff6a2c3f)
Merged-In: I2d54d99d62b54c39a6dc9064f8f62488433aff6f
Change-Id: I2d54d99d62b54c39a6dc9064f8f62488433aff6f
2026-05-08 21:46:19 +02:00
Lyon Wang
35e1532031
UPSTREAM: ANDROID: fs/passthrough: Fix compatibility with R/O file system
Look at the passthrough file and check to see if its mount is read-only.

Bug: 297482438
Signed-off-by: Lyon Wang <lyon.wang@mediatek.com>
Change-Id: I0f483c6bcb1effe395eee07b6d721f343840d115
(cherry picked from commit dbeed231965e1a01bf0d70ea5439fbfacc7c4aae)
2026-05-08 21:46:19 +02:00
liujinbao1
9545dda436
UPSTREAM: ANDROID: fuse-bpf: Add NULL pointer check in fuse_entry_revalidate
If userspace tried to add a backing file in a fuse_dentry_revalidate
where there wasn't one originally, this would trigger a crash. Disallow
this operation for now.

Bug: 296013218
Fixes: 57f3ff964899 ("ANDROID: fuse-bpf v1.1")

Test: fuse_test passes, following script no longer crashes:

adb shell su root setenforce 0
adb shell su root chmod ug+w /data/media
adb shell su root rm /data/media/Android -rf
adb shell su root mkdir -p /storage/emulated/Android/data/test
adb shell su root ls -l /storage/emulated/Android/data/test

Change-Id: Id8a67c43d1edfa010403d5f17e31109b796998cf
Signed-off-by: liujinbao1 <liujinbao1@xiaomi.corp-partner.google.com>
(cherry picked from commit e89b1266f784b2271af2e72a5d04e3e39d0afcdc)
2026-05-08 21:46:19 +02:00
Paul Lawrence
7b999dfdbb
UPSTREAM: ANDROID: fuse-bpf: Get correct inode in mkdir
We were getting the inode with the parent inode info
Also change variable names to remove confusion
Also set bpf correctly in new inode

Bug: 293838958
Test: fuse_test, atest ScopedStorageDeviceTest,
	atest CtsScopedStorageHostTest
Signed-off-by: Paul Lawrence <paullawrence@google.com>
(cherry picked from https://android-review.googlesource.com/q/commit:12eb00420cad77d7b7fcfbd1088c921ae629e69d)
Merged-In: I0b6a6951599e0d211afd2243daacb98679503448
Change-Id: I0b6a6951599e0d211afd2243daacb98679503448
2026-05-08 21:46:19 +02:00
Paul Lawrence
65d60dffad
UPSTREAM: ANDROID: fuse-bpf: Use stored bpf for create_open
create_open would always take its parent directory's bpf for the created
object. Modify to use the bpf stored in fuse_dentry which is set by
lookup.

Bug: 291705489
Test: fuse_test passes, adb push file /sdcard/Android/data works
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: I0a1ea2a291a8fdf67923f1827176b2ea96bd4c2d
2026-05-08 21:46:19 +02:00
Paul Lawrence
35003c2f72
UPSTREAM: ANDROID: fuse-bpf: Add bpf to negative fuse_dentry
Store the results of a negative lookup in the fuse_dentry so later
opcodes can use them to create files

Bug: 291705489
Test: fuse_test passes
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: I725e714a1d6ce43f24431d07c24e96349ef1a55c
2026-05-08 21:46:19 +02:00
Paul Lawrence
b0e557bef5
UPSTREAM: ANDROID: fuse-bpf: Check inode not null
fuse_iget_backing returns an inode or null, not a ERR_PTR. So check it's
not NULL

Also make sure we put the inode if d_splice_alias fails

Bug: 293349757
Test: fuse_test runs
Signed_off_by: Paul Lawrence <paullawrence@google.com>

Change-Id: I1eadad32f80bab6730e461412b4b7ab4d6c56bf2
2026-05-08 21:46:19 +02:00
Daniel Rosenberg
5c6d3f2618
UPSTREAM: ANDROID: fuse-bpf: Add partial ioctl support
This adds passthrough only support for ioctls with fuse-bpf.
compat_ioctls will return -ENOTTY.

Bug: 279519292
Test: F2fsMiscTest#testAtomicWrite
Change-Id: Ia3052e465d87dc1d15ae13955fba8a7f93bc387b
Signed-off-by: Daniel Rosenberg <drosen@google.com>
2026-05-08 21:46:19 +02:00
Daniel Rosenberg
293c259e5e
UPSTREAM: ANDROID: fuse-bpf: Add partial flock support
This adds passthrough support for flock on fuse-bpf files. It does not
give any control via a bpf filter. The flock will act as though it was
taken on the lower file.

Bug: 289882899
Test: fuse_test -t32 (flock_test)
Change-Id: Iba0b9630766cedbd3195532c5e929891593cfe30
Signed-off-by: Daniel Rosenberg <drosen@google.com>
2026-05-08 21:46:19 +02:00
Paul Lawrence
dfc8380342
UPSTREAM: ANDROID: fuse-bpf: Move FUSE_RELEASE to correct place
The existing fuse-bpf freeing logic would free the fuse_file struct
immediately. However, this would break readahead. Move freeing logic
to the same place as done in classic fuse.

Bug: 286287652
Test: fuse_test passes, android boots, cts tests run
Change-Id: If13519f0e956a8da0dc98e7ac4aed2036070e969
Signed-off-by: Paul Lawrence <paullawrence@google.com>
2026-05-08 21:46:19 +02:00
Paul Lawrence
8f058f1ced
UPSTREAM: ANDROID: fuse-bpf: Ensure bpf field can never be nulled
By putting and nulling fuse_inode's bpf field in fuse_evict_inode, we
left a race condition - this inode can still be active. Do not put the
bpf program until we are doing the final free in fuse_free_inode. This
was the root cause of the reported bug.

The backing inode cannot be put in fuse_free_inode, since put_inode can
sleep and this is called from an RCU handler. But the backing inode
cannot be freed until an RCU interval, so move the put_inode to the same
location as in overlayfs, which is destroy_inode.

Remove a path in fuse_handle_bpf_prog whereby bpf can be nulled out.
When we want to be able to null/change the bpf_prog in the future, we
will have to use a mutex or maybe RCU to protect existing users. But
until this time, ban this path.

Bug: 284450048
Test: fuse_test passes, Pixel 6 passes basic tests
Change-Id: Ie6844242f279a5b202eb021eac5a2dd3d08bf09d
Signed-off-by: Paul Lawrence <paullawrence@google.com>
2026-05-08 21:46:19 +02:00
Paul Lawrence
b0fc361eb2
UPSTREAM: ANDROID: fuse-bpf: Simplify and fix setting bpf program
Fix case when an existing bpf prog is being removed
Tidy up code

Bug: 279363668
Test: Boots, can copy file to /sdcardfs/Android/data, fuse_test passes
Change-Id: If0e682f43cbeb62764a7a2be543b90cb974b0aa0
Signed-off-by: Paul Lawrence <paullawrence@google.com>
2026-05-08 21:46:18 +02:00
Miklos Szeredi
4000339dc0
UPSTREAM: fuse: fix deadlock between atomic O_TRUNC and page invalidation
commit 2fdbb8dd01556e1501132b5ad3826e8f71e24a8b upstream.

fuse_finish_open() will be called with FUSE_NOWRITE set in case of atomic
O_TRUNC open(), so commit 76224355db75 ("fuse: truncate pagecache on
atomic_o_trunc") replaced invalidate_inode_pages2() by truncate_pagecache()
in such a case to avoid the A-A deadlock. However, we found another A-B-B-A
deadlock related to the case above, which will cause the xfstests
generic/464 testcase hung in our virtio-fs test environment.

For example, consider two processes concurrently open one same file, one
with O_TRUNC and another without O_TRUNC. The deadlock case is described
below, if open(O_TRUNC) is already set_nowrite(acquired A), and is trying
to lock a page (acquiring B), open() could have held the page lock
(acquired B), and waiting on the page writeback (acquiring A). This would
lead to deadlocks.

open(O_TRUNC)
----------------------------------------------------------------
fuse_open_common
  inode_lock            [C acquire]
  fuse_set_nowrite      [A acquire]

  fuse_finish_open
    truncate_pagecache
      lock_page         [B acquire]
      truncate_inode_page
      unlock_page       [B release]

  fuse_release_nowrite  [A release]
  inode_unlock          [C release]
----------------------------------------------------------------

open()
----------------------------------------------------------------
fuse_open_common
  fuse_finish_open
    invalidate_inode_pages2
      lock_page         [B acquire]
        fuse_launder_page
          fuse_wait_on_page_writeback [A acquire & release]
      unlock_page       [B release]
----------------------------------------------------------------

Besides this case, all calls of invalidate_inode_pages2() and
invalidate_inode_pages2_range() in fuse code also can deadlock with
open(O_TRUNC).

Fix by moving the truncate_pagecache() call outside the nowrite protected
region.  The nowrite protection is only for delayed writeback
(writeback_cache) case, where inode lock does not protect against
truncation racing with writes on the server.  Write syscalls racing with
page cache truncation still get the inode lock protection.

This patch also changes the order of filemap_invalidate_lock()
vs. fuse_set_nowrite() in fuse_open_common().  This new order matches the
order found in fuse_file_fallocate() and fuse_do_setattr().

Reported-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
Tested-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
Fixes: e4648309b8 ("fuse: truncate pending writes on O_TRUNC")
Cc: <stable@vger.kernel.org>
Change-Id: I7e01c787503114b4cd671ef7283fb0a1143887a1
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Jiachen Zhang
4056baf3cd
UPSTREAM: fuse: always revalidate rename target dentry
commit ccc031e26afe60d2a5a3d93dabd9c978210825fb upstream.

The previous commit df8629af2934 ("fuse: always revalidate if exclusive
create") ensures that the dentries are revalidated on O_EXCL creates.  This
commit complements it by also performing revalidation for rename target
dentries.  Otherwise, a rename target file that only exists in kernel
dentry cache but not in the filesystem will result in EEXIST if
RENAME_NOREPLACE flag is used.

Change-Id: Ie26ba53d008737ff709081dda0ef3e07ade449a5
Signed-off-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
Signed-off-by: Zhang Tianci <zhangtianci.1997@bytedance.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Miklos Szeredi
f6598346ec
UPSTREAM: fuse: fix attr version comparison in fuse_read_update_size()
commit 484ce65715b06aead8c4901f01ca32c5a240bc71 upstream.

A READ request returning a short count is taken as indication of EOF, and
the cached file size is modified accordingly.

Fix the attribute version checking to allow for changes to fc->attr_version
on other inodes.

Change-Id: I03143ae182ed264aea806a02c5ff4edf0ae28239
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Miklos Szeredi
9085f3d5d5
UPSTREAM: fuse: check s_root when destroying sb
commit d534d31d6a45d71de61db22090b4820afb68fddc upstream.

Checking "fm" works because currently sb->s_fs_info is cleared on error
paths; however, sb->s_root is what generic_shutdown_super() checks to
determine whether the sb was fully initialized or not.

This change will allow cleanup of sb setup error paths.

Change-Id: Icc78860e8a64e279fb2717b1cc08d1b83160d733
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Connor Kuehl
7a2f1138f9
UPSTREAM: virtiofs: split requests that exceed virtqueue size
commit a7f0d7aab0b4f3f0780b1f77356e2fe7202ac0cb upstream.

If an incoming FUSE request can't fit on the virtqueue, the request is
placed onto a workqueue so a worker can try to resubmit it later where
there will (hopefully) be space for it next time.

This is fine for requests that aren't larger than a virtqueue's maximum
capacity.  However, if a request's size exceeds the maximum capacity of the
virtqueue (even if the virtqueue is empty), it will be doomed to a life of
being placed on the workqueue, removed, discovered it won't fit, and placed
on the workqueue yet again.

Furthermore, from section 2.6.5.3.1 (Driver Requirements: Indirect
Descriptors) of the virtio spec:

  "A driver MUST NOT create a descriptor chain longer than the Queue
  Size of the device."

To fix this, limit the number of pages FUSE will use for an overall
request.  This way, each request can realistically fit on the virtqueue
when it is decomposed into a scattergather list and avoid violating section
2.6.5.3.1 of the virtio spec.

Change-Id: I78a1abfe6cb5484ec0f59c3aa841f119b6a5ff16
Signed-off-by: Connor Kuehl <ckuehl@redhat.com>
Reviewed-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Miklos Szeredi
d6738a5c66
UPSTREAM: virtiofs: clean up error handling in virtio_fs_get_tree()
commit 833c5a42e28beeefa1f9bd476a63fe8050c1e8ca upstream.

Avoid duplicating error cleanup.

Change-Id: I42491cd5c48689662186027b4ed123aa8d0d7908
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Yang Bo <yb203166@antfin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Paul Lawrence
69bb0347bf
UPSTREAM: ANDROID: fuse-bpf: Run bpf with migration disabled
To avoid a BUG_ON, we must disable migration before running any bpf
program.

Bug: 273620140
Test: fuse-test passes, no bug with CONFIG_DEBUG_ATOMIC_SLEEP
Change-Id: I9ed69ae93fc4b922782fccde293cb02b3eae3f06
Signed-off-by: Paul Lawrence <paullawrence@google.com>
(cherry picked from commit 0411f8d9dfa88e441456b5bcf684c5ec28ef08a7)
2026-05-08 21:46:18 +02:00
Paul Lawrence
0db2ea97e4
UPSTREAM: ANDROID: fuse-bpf: Correctly put backing files
Backing files were sometimes put twice before, this fixes it so backing
files sent in response to lookups are closed exactly once always

Test: fuse_test pases, Android no longer throws a double close
Bug: 273737310
Change-Id: Ifa75ffd846185cfabfd1f5bad504078d955c99ed
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Signed-off-by: Alistair Delva <adelva@google.com>
2026-05-08 21:46:18 +02:00
Paul Lawrence
7734b6d01d
UPSTREAM: ANDROID: fuse-bpf: Do not change bpf program in lookups
If a lookup finds an existing inode, it must not change the existing bpf
program since it may be in use.

Bug: 267095363
Test: fuse_test, atest CtsScopedStorageHostTest
Change-Id: Icb00681fbcd51fdd4b0764906509093d98caeec4
Signed-off-by: Paul Lawrence <paullawrence@google.com>
2026-05-08 21:46:18 +02:00
Miklos Szeredi
3a772729dd
BACKPORT: fuse: always revalidate if exclusive create
commit df8629af293493757beccac2d3168fe5a315636e upstream.

Failure to do so may result in EEXIST even if the file only exists in the
cache and not in the filesystem.

The atomic nature of O_EXCL mandates that the cached state should be
ignored and existence verified anew.

Reported-by: Ken Schalk <kschalk@nvidia.com>
Change-Id: I7bc67048363004f94dfe7b74d0873c019f06eaef
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Wu Bo <bo.wu@vivo.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-08 21:46:18 +02:00
Paul Lawrence
010f25aa35
UPSTREAM: ANDROID: fuse-bpf: Add /sys/fs flags for fuse-bpf version
Note that this is specific for the non-upstreamed version

Bug: 202785178
Test: cat /sys/fs/fuse/fuse_bpf_major_version
Change-Id: I68f9ca56778874975428839dfc1fd8f48b11bd75
Signed-off-by: Paul Lawrence <paullawrence@google.com>
2026-05-08 21:46:18 +02:00
Miklos Szeredi
ac8fa186fc
UPSTREAM: fuse: fix readdir cache race
[ Upstream commit 9fa248c65bdbf5af0a2f74dd38575acfc8dfd2bf ]

There's a race in fuse's readdir cache that can result in an uninitilized
page being read.  The page lock is supposed to prevent this from happening
but in the following case it doesn't:

Two fuse_add_dirent_to_cache() start out and get the same parameters
(size=0,offset=0).  One of them wins the race to create and lock the page,
after which it fills in data, sets rdc.size and unlocks the page.

In the meantime the page gets evicted from the cache before the other
instance gets to run.  That one also creates the page, but finds the
size to be mismatched, bails out and leaves the uninitialized page in the
cache.

Fix by marking a filled page uptodate and ignoring non-uptodate pages.

Reported-by: Frank Sorenson <fsorenso@redhat.com>
Fixes: 5d7bc7e868 ("fuse: allow using readdir cache")
Cc: <stable@vger.kernel.org> # v4.20
Change-Id: I1dea0531dd4d2cb0b89b8e1ee6796339fc2dc624
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-05-08 21:46:18 +02:00
Paul Lawrence
9769804365
UPSTREAM: ANDROID: fuse-bpf: set error_in to ENOENT in negative lookup
Bug: 250617797
Test: fuse-test passes, app installs
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: I44544f8989d0ddf00a98eaddce5751df6598130f
2026-05-08 21:46:18 +02:00
Paul Lawrence
3937d62267
UPSTREAM: ANDROID: fuse-bpf: readddir postfilter fixes
Test: fuse_test passes, with appropriate user code directories can be
hidden
Bug: 219958836
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: Ia77d4bf9e63d0dd4535e53e9e07c3216fd4b8430
2026-05-08 21:46:17 +02:00
Todd Kjos
defb79fa30
UPSTREAM: ANDROID: fix kernelci error in fs/fuse/dir.c
kernelci reported the following error when !CONFIG_FUSE_BPF:

fs/fuse/dir.c:269:40: error: no member named 'backing_inode' in 'struct fuse_inode'

Fixed by wrapping that new code in #ifdef CONFIG_FUSE_BPF.

Fixes: 094905c87771 ("ANDROID: fuse-bpf: Always call revalidate for
backing")
Signed-off-by: Todd Kjos <tkjos@google.com>
Change-Id: I08760f340cebf21d3084ca84ac1792bc70f311ff
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
e36a3e56c9
UPSTREAM: ANDROID: fuse-bpf: Fix RCU/reference issue
094905c87771 ("ANDROID: fuse-bpf: Always call revalidate for backing")
called dget_parent/dput improperly within an RCU context. Additionally,
it failed to free/put some references.

Fixes: 094905c87771 ("ANDROID: fuse-bpf: Always call revalidate for backing")
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Iedeee7550ff88366bc5310eedece285019336814
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
4e5cea6bec
UPSTREAM: ANDROID: fuse-bpf: Always call revalidate for backing
If we have a backing dentry, we must call it's revalidate always, or we
may end up using an invalid lower dentry. Revalidate is called for
dentries, not inodes, and the dentry may be negative. This goes against
all of the macro conventions, so we're just calling the backing function
directly.

Signed-off-by: Daniel Rosenberg <drosen@google.com>
Bug: 219958836
Test: fuse_test
Change-Id: Ia28da5bd2ce42b40466c577137d5440d9f2f6600
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
1874580176
UPSTREAM: ANDROID: fuse-bpf: Adjust backing handle funcs
Cleaned up some args, and adjusted so we can choose to not update the
actual values for the next patch.

Test: fuse_test
Bug: 219958836
Change-Id: I025b7026357b119e2cd588f25f0976f5d4b68090
Signed-off-by: Daniel Rosenberg <drosen@google.com>
2026-05-08 21:46:17 +02:00
Dmitrii Merkurev
306c4b88cf
UPSTREAM: ANDROID: fuse-bpf: Fix revalidate error path and backing handling
Currently we have 2 different problems

1. Every revalidate considered as a error because of added
args->out_argvar = true; inside fuse_lookup_init which makes
fuse_simple_request return out argument size which is
considered as an error by revalidate code.

2. We’re ignoring backing_fd and bpf_program set by daemon
lookup code called by revalidate.

Problem 1 makes any revalidate (lookup to userspace) useless and any result
lead us to the full lookup because it was interpreted as an error.

This CL fixes both and introducing revalidate test case which makes sure:

1. We’re receiving only one lookup as a part of revalidate
2. We’re setting backing_fd as a part of revalidate’s lookup result

Test is failed before the fix and passed after.

Bug: 219958836
Test: Booted device 5 times to make sure we’re not receiving redundant
lookups anymore.
Test: selftests
Signed-off-by: Dmitrii Merkurev <dimorinny@google.com>
Change-Id: Ifa62e56b42ca5580b25682eb5f16b5c91826cf49
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
a82e300d0c
UPSTREAM: ANDROID: fuse: Don't use readdirplus w/ nodeid 0
If we have a nodeid of 0, we've probably got a backing inode, and a
regular getattr will be fast. Otherwise, userspace is likely ill suited
to properly handle a readdirplus anyways.

Test: fuse_test
Bug: 219958836
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I02f031d87dcc5fcbe1e080e4f8ec92187b00fe2d
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
f72a971ce7
UPSTREAM: ANDROID: fuse-bpf: Fix use of get_fuse_inode
get_fuse_inode uses container_of, which results in a strange result if
the inode is NULL. We should check if the inode is NULL instead.

Fixes: 4ad093cae178 ("ANDROID: fuse-bpf: Make inodes with backing_fd reachable")
Bug: 219958836
Change-Id: I386c4641edaa4dbc8d8e02f592c959c206851eda
Signed-off-by: Daniel Rosenberg <drosen@google.com>
2026-05-08 21:46:17 +02:00
Dmitrii Merkurev
3f557cd122
UPSTREAM: ANDROID: fuse-bpf: Make sure force_again flag is false by default
Usage of uninitialized boolean is potentially can cause annoying
and “hard to catch” types of problems. Currently we have 1
case where we use uninitialized boolean:

int fuse_readdir(struct file *file, struct dir_context *ctx)

And I constantly see that every userspace readdir operation
causes an infinite cycle inside the Kernel for my QEMU tests
(gcc).
This problem isn’t reproducible inside cuttlefish, probably
because we use clang toolchain.

Bug: 219958836
Test: atest ScopedStorageDeviceTest
Test: selftests
Change-Id: I2c38056448cd2910e0cb20da5839d7db9ebd26b9
Signed-off-by: Dmitrii Merkurev <dimorinny@google.com>
2026-05-08 21:46:17 +02:00
Dmitrii Merkurev
95d31c5b4c
UPSTREAM: ANDROID: fuse-bpf: Make inodes with backing_fd reachable
for regular FUSE fuse_iget

Currently, when we’re trying to find inode based on their
backing inode we strictly checking on nodeid == 0, so
basically we’re not supporting nodeid != 0 for inode,
which is backed by another one. Alongside with this, we’re
using backing_inode as a hash for inode which make this inode
not reachable for regular FUSE fuse_iget that as a result
causing backing_inode losing because instead of getting
existent one (with backing inode) we create a new one as
a part of readdirplus.

For more details please check: go/fuse-loosing-inode-with-backing

Bug: 219958836
Test: Manually checked that /data and /obb inodes
always have inode numbers configured.
Co-developed-by: Paul Lawrence <paullawrence@google.com>

Change-Id: If6a5fb340561ac6320d3c4e86215f1bcd4c2c10c
Signed-off-by: Dmitrii Merkurev <dimorinny@google.com>
2026-05-08 21:46:17 +02:00
Dmitrii Merkurev
c01add08ee
UPSTREAM: Revert "ANDROID: fuse-bpf: use target instead of parent inode
to execute backing revalidate"

This reverts commit b610eff230f2ce92fd48502d71ad0993792f73d3.

Reason for revert: I broke BPF calling logic with this one. Possible
fix is here:
https://android-review.googlesource.com/c/kernel/common/+/2132134 but
we're still discussing possible way to go there:
go/fuse-bpf-revalidate-problem
Change-Id: I517941a2c341999dc8133b93cf045ec67bcf8a9e
Signed-off-by: Dmitrii Merkurev <dimorinny@google.com>
2026-05-08 21:46:17 +02:00
Dmitrii Merkurev
99f0eb0da8
UPSTREAM: ANDROID: fuse-bpf: use target instead of parent inode to execute backing revalidate
Usually as a result of initial fuse lookup with bpf enabled we have following dentry:
 -----------------------------------------------------------------
|  dentry /storage/emulated/0/Android/data                        |
|     inode                                                       |
|        backing_inode: /pass_through/emulated/0/Android/data     |
 -----------------------------------------------------------------

Every communication with this folder will have to go
through fuse_dentry_revalidate(dentry, flags) which can move forward by:

1. If the timeout is not reached, just ignore it
2. If entry has backing_inode and bpf is not against it, execute revalidate on backing FS (inside kernel)
3. Move to userspace to revalidate

But for some reason currently, we're checking parent inode (not one that we wanna revalidate) to have
backing inode that we can use to execute operations on. Basically, the whole flow looks like this:

1. Receiving revalidate event for fuse_dentry_revalidate(/storage/emulated/0/Android/data, flags)
2. Checking .../0/Android/ inode to have backing inode <------------------------ Primary problem is HERE
3. Moving to the userspace with pf_lookup(/storage/emulated/0/Android, data)
4. Even though successfully handled lookup on the fuse daemon side, kernel cannot interpret
the result due to fuse_simple_request and fuse_lookup_init logic changes <------- Secondary problem is HERE
5. Because of the problems I mentioned before, full lookup is triggered on the kernel side so we receive the second pf_lookup to the userspace

Fixing primary problem by executing backing revalidate on the current inode (not the parent one).

Bug: 234346312
Test: Manually made sure don't have any userspace calls for interactions inside directory with backing one.
Test: Manually check youtube app is successfully saving exo cache into the external storage cache folder.
Test: atest --test-mapping packages/providers/MediaProvider
Signed-off-by: Dmitrii Merkurev <dimorinny@google.com>
Change-Id: Id57f1944302076d93ebef255533dfc53e8c30f20
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
5387caaa4b
UPSTREAM: ANDROID: fuse-bpf: Fix non-fusebpf build
Added #ifdefs around fuse-bpf init/cleanup code

Bug: 202785178
Test: builds with and without CONFIG_FUSE_BPF
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Ie15bb04e439b496e4842303437b3f55c3da14f2c
2026-05-08 21:46:17 +02:00
Paul Lawrence
3665b480d1
UPSTREAM: ANDROID: fuse-bpf: Fix misuse of args.out_args
Test: fuse_test
Bug: 202785178
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: I332d196329bba257a577d3ddc140136aa03bfdf1
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
29efcdd0db
BACKPORT: ANDROID: fuse-bpf: Use fuse_bpf_args in uapi
fuse_args is not suitable for use in the uapi - it is not stable, and
contains internal pointers. Replace with stable equivalent.

The end_offset values are currently unused and unset, but will be used
in a follow up patch by the verifier.

Test: fuse_test, atest ScopedStorageDeviceTest pass
Bug: 202785178
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Ic1c12f9706aeae233cc30a0d68ed2533030e485b
2026-05-08 21:46:17 +02:00
Daniel Rosenberg
d0df659ec7
UPSTREAM: ANDROID: fuse-bpf: Fix read_iter
We had a size mismatch for the return value, leading to EIOCBQUEUED
getting interpreted as a return size instead of an error code.

Test: generic/467, generic/013, and fuse_test
Bug: 217570523
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I64f9d5263f8b37d3c0e286467f9351997b294cc2
2026-05-08 21:46:16 +02:00
Daniel Rosenberg
426f86751b
UPSTREAM: ANDROID: fuse-bpf: Use cache and refcount
Allocates the iocb we create for asynchronous IO from a cache instead of
a regular kzalloc

Test: generic/467 and fuse_test
Bug: 217570523
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I27dcec89cd585835f6a8e80e1ae30c503f4038c8
2026-05-08 21:46:16 +02:00
Daniel Rosenberg
20edac301a
UPSTREAM: ANDROID: fuse-bpf: Rename iocb_fuse to iocb_orig
The current name is a bit confusing. iocb_fuse could refer to the iocb
passed to fuse or created by fuse. The new name unambiguously refers to
the one passed in to fuse.

Test: compiles, behavior unchanged
Bug: 217570523
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I955500eb8a3186252427fd06ca6e99b4fec469b6
2026-05-08 21:46:16 +02:00
Daniel Rosenberg
0ae10ca8d1
UPSTREAM: ANDROID: fuse-bpf: Fix fixattr in rename
Existing fixattr was adjusting the same node twice.

Bug: 226655982
Test: generic/241 generic/269
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: I4b1cb6d626ee6bd9010012ac126b78f14d6157d0
2026-05-08 21:46:16 +02:00
Daniel Rosenberg
f1135a3332
UPSTREAM: ANDROID: fuse-bpf: Fix readdir
Fuse uses generic_file_llseek, so we must account for that in readdir to
ensure we read from the correct offset in the lower filesystem.

Bug: 226655281
Test: generic/257, fuse_test
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Ie752c1c645e95b7c03ef9497562758a5c42b514a
2026-05-08 21:46:16 +02:00
Paul Lawrence
2921af70c5
UPSTREAM: ANDROID: fuse-bpf: Fix lseek return value for offset 0
Bug: 227160050
Test: audible app now works
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: Ib14765285190b5838f28c25a69c91935d02c34f4
2026-05-08 21:46:16 +02:00
Daniel Rosenberg
11a6e05d2c
UPSTREAM: ANDROID: fuse-bpf: fix read_iter and write_iter
Properly handle the async case. The existing bpf operations will likely
need to be reworked. Given that they don't allow altering anything as
is, this change just incrementally moves us in the right direction.

Signed-off-by: Daniel Rosenberg <drosen@google.com>
Test: generic/467 and fuse_test
Bug: 217570523
Change-Id: I31c0b48bf3d674efecad4bff4ea8b482c4e7da45
2026-05-08 21:46:16 +02:00