Android 12 mendukung passthrough FUSE, yang meminimalkan
overhead FUSE untuk mencapai performa yang sebanding dengan akses langsung ke sistem file
yang lebih rendah. Passthrough FUSE didukung dalam kernel android12-5.4
,
android12-5.10
, dan android-mainline
(hanya pengujian), yang berarti
bahwa dukungan untuk fitur ini bergantung pada kernel yang digunakan oleh perangkat dan
versi Android yang dijalankan perangkat:
Perangkat yang diupgrade dari Android 11 ke Android 12 tidak dapat mendukung passthrough FUSE karena kernel untuk perangkat ini dibekukan dan tidak dapat berpindah ke kernel yang telah diupgrade secara resmi dengan perubahan passthrough FUSE.
Perangkat yang diluncurkan dengan Android 12 dapat mendukung passthrough FUSE saat menggunakan kernel resmi. Untuk perangkat tersebut, kode framework Android yang mengimplementasikan passthrough FUSE disematkan dalam modul utama MediaProvider, yang diupgrade secara otomatis. Perangkat yang tidak menerapkan MediaProvider sebagai modul utama (misalnya, perangkat Android Go), juga dapat mengakses perubahan MediaProvider karena dibagikan secara publik.
FUSE versus SDCardFS
Sistem file di Userspace (FUSE) adalah mekanisme yang memungkinkan operasi yang dilakukan pada sistem file FUSE untuk di-outsource oleh kernel (driver FUSE) ke program ruang pengguna (daemon FUSE), yang mengimplementasikan operasi. Android 11 tidak lagi menggunakan SDCardFS dan menjadikan FUSE sebagai solusi default untuk emulasi penyimpanan. Sebagai bagian dari perubahan ini, Android menerapkan daemon FUSE-nya sendiri untuk mencegat akses file, menerapkan fitur keamanan dan privasi tambahan, serta memanipulasi file saat runtime.
Meskipun FUSE berperforma baik saat menangani informasi yang dapat di-cache seperti halaman atau atribut, FUSE akan menyebabkan regresi performa saat mengakses penyimpanan eksternal yang terutama terlihat di perangkat kelas menengah dan kelas bawah. Regresi ini disebabkan oleh rantai komponen yang bekerja sama dalam implementasi sistem file FUSE, serta beberapa tombol dari ruang kernel ke ruang pengguna dalam komunikasi antara driver FUSE dan Daemon FUSE (dibandingkan dengan akses langsung ke sistem file yang lebih rendah yang lebih ramping dan diimplementasikan sepenuhnya di kernel).
Untuk mengurangi regresi, aplikasi dapat menggunakan
penyambungan untuk
mengurangi penyalinan data dan menggunakan ContentProvider
API
untuk mendapatkan akses langsung ke file sistem file yang lebih rendah. Meskipun dengan hal ini dan pengoptimalan
lainnya, operasi
baca dan tulis mungkin mengalami penurunan bandwidth saat menggunakan FUSE jika dibandingkan
dengan akses langsung ke sistem
file yang lebih rendah — terutama dengan operasi baca
acak, yang tidak dapat dibantu oleh caching atau read-ahead. Selain itu, aplikasi yang langsung
mengakses penyimpanan melalui jalur /sdcard/
lama terus mengalami
penurunan performa yang signifikan, terutama saat melakukan operasi
yang intensif IO.
Permintaan ruang pengguna SDcardFS
Menggunakan SDcardFS dapat mempercepat emulasi penyimpanan dan pemeriksaan izin FUSE dengan menghapus panggilan ruang pengguna dari kernel. Permintaan ruang pengguna mengikuti jalur: Ruang pengguna → VFS → sdcardfs → VFS → ext4 → Cache halaman/Penyimpanan.
Gambar 1. Permintaan ruang pengguna SDcardFS
Permintaan ruang pengguna FUSE
FUSE awalnya digunakan untuk mengaktifkan emulasi penyimpanan dan memungkinkan aplikasi menggunakan penyimpanan internal atau kartu SD eksternal secara transparan. Penggunaan FUSE memperkenalkan beberapa overhead karena setiap permintaan userspace mengikuti jalur: Userspace → VFS → Driver FUSE → daemon FUSE → VFS → ext4 → Cache/Storage halaman.
Gambar 2. Permintaan ruang pengguna FUSE
Permintaan passthrough FUSE
Sebagian besar izin akses file diperiksa pada waktu file dibuka, dengan pemeriksaan izin tambahan yang terjadi saat membaca dari dan menulis ke file tersebut. Dalam beberapa kasus, Anda dapat mengetahui pada waktu file dibuka bahwa aplikasi yang meminta memiliki akses penuh ke file yang diminta, sehingga sistem tidak perlu terus meneruskan permintaan baca dan tulis dari driver FUSE ke daemon FUSE (karena hanya akan memindahkan data dari satu tempat ke tempat lain).
Dengan passthrough FUSE, daemon FUSE yang menangani permintaan terbuka dapat memberi tahu driver FUSE bahwa operasi diizinkan dan semua permintaan baca dan tulis berikutnya dapat langsung diteruskan ke sistem file yang lebih rendah. Tindakan ini menghindari overhead tambahan saat menunggu daemon FUSE ruang pengguna membalas permintaan driver FUSE.
Perbandingan permintaan passthrough FUSE dan FUSE ditampilkan di bawah.
Gambar 3. Permintaan FUSE versus permintaan passthrough FUSE
Saat aplikasi melakukan akses sistem file FUSE, operasi berikut akan terjadi:
Driver FUSE menangani dan mengantrekan permintaan, lalu menyajikannya ke daemon FUSE yang menangani sistem file FUSE tersebut melalui instance koneksi tertentu pada file
/dev/fuse
, yang diblokir agar tidak dapat dibaca oleh daemon FUSE.Saat menerima permintaan untuk membuka file, daemon FUSE akan memutuskan apakah passthrough FUSE harus tersedia untuk file tertentu tersebut. Jika tersedia, daemon:
Memberi tahu driver FUSE tentang permintaan ini.
Mengaktifkan passthrough FUSE untuk file menggunakan ioctl
FUSE_DEV_IOC_PASSTHROUGH_OPEN
, yang harus dilakukan pada deskriptor file dari/dev/fuse
yang dibuka.
ioctl menerima (sebagai parameter) struktur data yang berisi hal berikut:
Deskriptor file dari file sistem file yang lebih rendah yang merupakan target untuk fitur passthrough.
ID unik permintaan FUSE yang saat ini sedang ditangani (harus terbuka atau buat-dan-buka).
Kolom tambahan yang dapat dibiarkan kosong dan dimaksudkan untuk penerapan mendatang.
Jika ioctl berhasil, daemon FUSE akan menyelesaikan permintaan yang terbuka, driver FUSE menangani balasan daemon FUSE, dan referensi ke file sistem file yang lebih rendah ditambahkan ke file FUSE dalam kernel. Saat aplikasi meminta operasi baca/tulis pada file FUSE, driver FUSE akan memeriksa apakah referensi ke file sistem file yang lebih rendah tersedia.
Jika referensi tersedia, driver akan membuat permintaan Virtual File System (VFS) baru dengan parameter yang sama yang menargetkan file sistem file yang lebih rendah.
Jika referensi tidak tersedia, driver akan meneruskan permintaan ke daemon FUSE.
Operasi di atas terjadi untuk operasi baca/tulis dan iterasi baca/tulis pada file umum dan operasi baca/tulis pada file yang dipetakan memori. Passthrough FUSE untuk file tertentu ada hingga file tersebut ditutup.
Mengimplementasikan passthrough FUSE
Untuk mengaktifkan passthrough FUSE di perangkat yang menjalankan Android
12, tambahkan baris berikut ke
file $ANDROID_BUILD_TOP/device/…/device.mk
perangkat target.
# Use FUSE passthrough
PRODUCT_PRODUCT_PROPERTIES += \
persist.sys.fuse.passthrough.enable=true
Untuk menonaktifkan passthrough FUSE, hapus perubahan konfigurasi di atas atau tetapkan
persist.sys.fuse.passthrough.enable
ke false
. Jika sebelumnya Anda telah mengaktifkan
passthrough FUSE, menonaktifkannya akan mencegah perangkat menggunakan passthrough FUSE
tetapi perangkat tetap berfungsi.
Untuk mengaktifkan/menonaktifkan passthrough FUSE tanpa mem-flash perangkat, ubah properti sistem menggunakan perintah ADB. Contohnya ditampilkan di bawah ini.
adb root
adb shell setprop persist.sys.fuse.passthrough.enable {true,false}
adb reboot
Untuk bantuan tambahan, lihat penerapan referensi.
Memvalidasi passthrough FUSE
Untuk memvalidasi bahwa MediaProvider menggunakan passthrough FUSE, periksa logcat
untuk
pesan proses debug. Contoh:
adb logcat FuseDaemon:V \*:S
--------- beginning of main
03-02 12:09:57.833 3499 3773 I FuseDaemon: Using FUSE passthrough
03-02 12:09:57.833 3499 3773 I FuseDaemon: Starting fuse...
Entri FuseDaemon: Using FUSE passthrough
dalam log memastikan bahwa passthrough
FUSE sedang digunakan.
CTS Android 12 menyertakan CtsStorageTest
, yang
menyertakan pengujian yang memicu passthrough FUSE. Untuk menjalankan pengujian secara manual, gunakan
atest seperti yang ditunjukkan di bawah:
atest CtsStorageTest