summaryrefslogtreecommitdiff
path: root/jni
diff options
context:
space:
mode:
author Daniel Rosenberg <drosen@google.com> 2025-02-10 16:34:58 -0800
committer Daniel Rosenberg <drosen@google.com> 2025-02-11 17:40:27 -0800
commit5e6bbfdc481cd78c057d5b46b53195ace8858e09 (patch)
tree0b24b8a1668980c6c72341c9735dc2a829d297f1 /jni
parent923b3a9b441efa579eeb59e20395c41a79a37b02 (diff)
Check for modified upstream passthrough before using
Android requires changes to upstream passthrough to be able to use it successfully. If these changes are not present, do not use it. Bug: 376007121 Flag: EXEMPT bugfix Test: Boot mainline kernel without fuse_passthrough sysfs entry Device should not use upstream passthrough Change-Id: I051cf898bcc8825c43e36012c9baaaf248ca66d5
Diffstat (limited to 'jni')
-rw-r--r--jni/FuseDaemon.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index fb0468c5b..a89819e52 100644
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -713,6 +713,28 @@ namespace fuse {
*
*/
+bool IsUpstreamPassthroughSupported() {
+ // Upstream passthrough requires some modifications to work. If those are present,
+ // /sys/fs/fuse/fuse_passthrough will read 'supported\n'
+ // - see fs/fuse/inode.c in the kernel source
+
+ string contents;
+ const char* filename = "/sys/fs/fuse/features/fuse_passthrough";
+ if (!android::base::ReadFileToString(filename, &contents)) {
+ LOG(INFO) << "fuse-passthrough is disabled because " << filename << " cannot be read";
+ return false;
+ }
+
+ if (contents == "supported\n") {
+ LOG(INFO) << "fuse-passthrough is enabled because " << filename << " reads 'supported'";
+ return true;
+ } else {
+ LOG(INFO) << "fuse-passthrough is disabled because " << filename
+ << " does not read 'supported'";
+ return false;
+ }
+}
+
static void pf_init(void* userdata, struct fuse_conn_info* conn) {
struct fuse* fuse = reinterpret_cast<struct fuse*>(userdata);
@@ -752,7 +774,8 @@ static void pf_init(void* userdata, struct fuse_conn_info* conn) {
// b. Files requiring redaction are still faster than no-passthrough devices that use
// direct_io
disable_splice_write = true;
- } else if (conn->capable & FUSE_CAP_PASSTHROUGH_UPSTREAM) {
+ } else if ((conn->capable & FUSE_CAP_PASSTHROUGH_UPSTREAM) &&
+ IsUpstreamPassthroughSupported()) {
mask |= FUSE_CAP_PASSTHROUGH_UPSTREAM;
disable_splice_write = true;
fuse->upstream_passthrough = true;
@@ -1451,7 +1474,7 @@ static handle* create_handle_for_node(struct fuse* fuse, const string& path, int
}
if (fuse->passthrough && allow_passthrough) {
- *keep_cache = transforms_complete && !fuse->upstream_passthrough;
+ *keep_cache = transforms_complete;
// We only enabled passthrough iff these 2 conditions hold
// 1. Redaction is not needed
// 2. Node transforms are completed, e.g transcoding.