[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-04。"],[],[],null,["# FUSE passthrough\n\nAndroid 12 supports FUSE passthrough, which minimizes\nFUSE overhead to achieve performance comparable to direct access to the lower\nfile system. FUSE passthrough is supported in the `android12-5.4`,\n`android12-5.10`, and `android-mainline` (testing only) kernels, which means\nthat support for this feature depends on the kernel used by the device and the\nversion of Android the device is running:\n\n- Devices upgrading from Android 11 to Android 12 can't\n support FUSE passthrough as the kernels for these devices are frozen and they\n can't move to a kernel that's been officially upgraded with the FUSE\n passthrough changes.\n\n- Devices launching with Android 12 can support FUSE\n passthrough when using an official kernel. For such devices, the Android\n framework code that implements FUSE passthrough is embedded in the\n [MediaProvider](/docs/core/media/media-provider) mainline module, which\n is automatically upgraded. Devices that don't implement MediaProvider as a\n mainline module (for example, Android Go devices), can also access\n MediaProvider changes as they are publicly shared.\n\nFUSE versus SDCardFS\n--------------------\n\n[File system in Userspace\n(FUSE)](https://github.com/libfuse/libfuse) is a mechanism that\nallows operations performed on a FUSE file system to be outsourced by the kernel\n(FUSE driver) to a userspace program (FUSE daemon), which implements the\noperations. Android 11 [deprecated\nSDCardFS](/docs/core/storage/sdcardfs-deprecate) and made FUSE the default\nsolution for storage emulation. As part of this change, Android implemented its\nown FUSE daemon to intercept file accesses, enforce extra security and privacy\nfeatures, and manipulate files at runtime.\n\nWhile FUSE performs well when dealing with cacheable information such as pages\nor attributes, it introduces performance regressions when accessing external\nstorage that are especially visible in mid and low-end devices. These\nregressions are caused by a chain of components cooperating in the\nimplementation of the FUSE file system, as well as multiple switches from kernel\nspace to user space in communications between the FUSE driver and the FUSE\ndaemon (as compared to direct access to the lower file system that is leaner and\ncompletely implemented in the kernel).\n\nTo mitigate these regressions, apps can use\n[splicing](https://en.wikipedia.org/wiki/Splice_(system_call)) to\nreduce data copying and use the [ContentProvider\nAPI](https://developer.android.com/reference/android/content/ContentProvider)\nto get direct access to lower file system files. Even with these and [other\noptimizations](/docs/core/storage/scoped#fuse-performance-tuning), read\nand write operations might see reduced bandwidth when using FUSE when compared\nto direct access to the lower file\nsystem --- especially with random read\noperations, where no caching or read-ahead can help. And apps that directly\naccess storage through the legacy `/sdcard/` path continue to experience\nnoticeable performance drops, especially when performing IO-intensive\noperations.\n\n### SDcardFS userspace requests\n\nUsing SDcardFS can speed up the storage emulation and permission checks of FUSE\nby removing the user space call from the kernel. Userspace requests follow the\npath: Userspace → VFS → sdcardfs → VFS → ext4 → Page cache/Storage.\n\n**Figure 1.** SDcardFS userspace requests\n\n### FUSE userspace requests\n\nFUSE was initially used to enable storage emulation and to allow apps to\ntransparently use either the internal storage or an external sdcard. Using FUSE\nintroduces some overhead because each userspace request follows the path:\nUserspace → VFS → FUSE driver → FUSE daemon → VFS → ext4 → Page cache/Storage.\n\n**Figure 2.** FUSE userspace requests\n\nFUSE passthrough requests\n-------------------------\n\nMost file access permissions are checked at file open time, with additional\npermissions checks occurring when reading from and writing to that file. In some\ncases, it's possible to know at file open time that the requesting app has full\naccess to the requested file, so the system doesn't need to continue forwarding\nread and write the requests from the FUSE driver to the FUSE daemon (as that\nwould only move data from one place to another).\n\nWith FUSE passthrough, the FUSE daemon handling an open request can notify the\nFUSE driver that the operation is allowed and that all subsequent read and write\nrequests can be directly forwarded to the lower file system. This avoids the\nextra overhead of waiting for the user space FUSE daemon to reply to the FUSE\ndriver requests.\n\nA comparison of FUSE and FUSE passthrough requests is shown below.\n\n**Figure 3.** FUSE request versus FUSE passthrough request\n\nWhen an app performs a FUSE file system access, the following operations occur:\n\n1. The FUSE driver handles and enqueues the request, then presents it to the\n FUSE daemon that handles that FUSE file system through a specific connection\n instance on the `/dev/fuse` file, which the FUSE daemon is blocked from\n reading.\n\n2. When the FUSE daemon receives a request to open a file, it decides whether\n FUSE passthrough should be available for that particular file. If it's\n available, the daemon:\n\n 1. Notifies the FUSE driver about this request.\n\n 2. Enables FUSE passthrough for the file using the\n `FUSE_DEV_IOC_PASSTHROUGH_OPEN` ioctl, which must be performed on the\n file descriptor of the opened `/dev/fuse`.\n\n3. The ioctl receives (as a parameter) a data structure that contains the\n following:\n\n - File descriptor of the lower file system file that's the target for the\n passthrough feature.\n\n - Unique identifier of the FUSE request that is currently being handled (must\n be open or create-and-open).\n\n - Extra fields that can be left empty and are meant for future\n implementations.\n\n4. If the ioctl succeeds, the FUSE daemon completes the open request, the FUSE\n driver handles the FUSE daemon reply, and a reference to the lower file\n system file is added to the FUSE file within the kernel. When an app requests\n a read/write operation on a FUSE file, the FUSE driver checks if the\n reference to a lower file system file is available.\n\n - If a reference is available, the driver creates a new Virtual File System\n (VFS) request with the same parameters targeting the lower file system\n file.\n\n - If a reference isn't available, the driver forwards the request to the FUSE\n daemon.\n\nThe above operations occur for read/write and read-iter/write-iter on generic\nfiles and read/write operations on memory-mapped files. FUSE passthrough for a\ngiven file exists until that file is closed.\n\nImplement FUSE passthrough\n--------------------------\n\nTo enable FUSE passthrough on devices running Android\n12, add the following lines to the\n`$ANDROID_BUILD_TOP/device/.../device.mk` file of the target device. \n\n # Use FUSE passthrough\n PRODUCT_PRODUCT_PROPERTIES += \\\n persist.sys.fuse.passthrough.enable=true\n\nTo disable FUSE passthrough, omit the above configuration change or set\n`persist.sys.fuse.passthrough.enable` to `false`. If you've previously enabled\nFUSE passthrough, disabling it prevents the device from using FUSE passthrough\nbut the device remains functional.\n| **Note:** Ensure that all kernel and Android framework elements needed to implement FUSE passthrough are present, otherwise changing `persist.sys.fuse.passthrough.enable` has no effect.\n\nTo enable/disable FUSE passthrough without flashing the device, change the\nsystem property using ADB commands. An example is shown below. \n\n adb root\n adb shell setprop persist.sys.fuse.passthrough.enable {true,false}\n adb reboot\n\nFor additional help, refer to the [reference\nimplementation](https://lore.kernel.org/lkml/20210125153057.3623715-1-balsini@android.com/).\n\nValidate FUSE passthrough\n-------------------------\n\nTo validate that MediaProvider is using FUSE passthrough, check `logcat` for\ndebugging messages. For example: \n\n adb logcat FuseDaemon:V \\*:S\n --------- beginning of main\n 03-02 12:09:57.833 3499 3773 I FuseDaemon: Using FUSE passthrough\n 03-02 12:09:57.833 3499 3773 I FuseDaemon: Starting fuse...\n\nThe `FuseDaemon: Using FUSE passthrough` entry in the log ensures that FUSE\npassthrough is in use.\n| **Note:** If logcat displays error messages related to FUSE passthrough, some components might be missing or outdated.\n\nThe Android 12 CTS includes `CtsStorageTest`, which\nincludes tests that trigger FUSE passthrough. To run the test manually, use\natest as shown below: \n\n atest CtsStorageTest"]]