diff options
author | 2025-02-10 16:34:58 -0800 | |
---|---|---|
committer | 2025-02-11 17:40:27 -0800 | |
commit | 5e6bbfdc481cd78c057d5b46b53195ace8858e09 (patch) | |
tree | 0b24b8a1668980c6c72341c9735dc2a829d297f1 /jni | |
parent | 923b3a9b441efa579eeb59e20395c41a79a37b02 (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.cpp | 27 |
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. |