Android 12, alt dosya sistemine doğrudan erişimle benzer performans elde etmek için FUSE yükü en aza indiren FUSE geçişini destekler. FUSE geçişi, android12-5.4
, android12-5.10
ve android-mainline
(yalnızca test) çekirdeklerinde desteklenir. Bu, bu özelliğin desteğinin cihaz tarafından kullanılan çekirdeğe ve cihazın çalıştırmakta olduğu Android sürümüne bağlı olduğu anlamına gelir:
Android 11'den Android 12'ye yükseltilen cihazlar, bu cihazların çekirdekleri dondurulduğu ve FUSE geçiş değişiklikleriyle resmi olarak yükseltilmiş bir çekirdeğe geçemediği için FUSE geçişini destekleyemez.
Android 12 ile kullanıma sunulan cihazlar, resmi bir çekirdek kullanırken FUSE geçişini destekleyebilir. Bu tür cihazlarda, FUSE geçişini uygulayan Android çerçeve kodu, otomatik olarak yükseltilen MediaProvider ana hat modülüne yerleştirilir. MediaProvider'ı ana modül olarak uygulamayan cihazlar (ör. Android Go cihazları) da herkese açık olarak paylaşılan MediaProvider değişikliklerine erişebilir.
FUSE ve SDCardFS
Kullanıcı alanındaki dosya sistemi (FUSE), FUSE dosya sisteminde gerçekleştirilen işlemlerin çekirdek (FUSE sürücüsü) tarafından kullanıcı alanındaki bir programa (FUSE daemon'ı) yaptırılmasına olanak tanıyan bir mekanizmadır. Android 11, SDCardFS desteğini sonlandırdı ve depolama alanı emülasyonu için varsayılan çözümü FUSE yaptı. Bu değişiklik kapsamında Android, dosya erişimlerini durdurmak, ek güvenlik ve gizlilik özelliklerini zorunlu kılmak ve dosyaları çalışma zamanında değiştirmek için kendi FUSE daemon'ını uyguladı.
FUSE, sayfa veya özellikler gibi önbelleğe alınabilir bilgilerle çalışırken iyi performans gösterirken harici depolamaya erişirken özellikle orta ve düşük kaliteli cihazlarda görülebilen performans gerilemelerine neden olur. Bu gerilemelerin nedeni, FUSE dosya sisteminin uygulanmasında birlikte çalışan bir bileşen zinciri ve FUSE sürücüsü ile FUSE hizmet programı arasındaki iletişimde çekirdek alanından kullanıcı alanına yapılan birden fazla geçiştir (daha basit ve çekirdekte tamamen uygulanmış alt dosya sistemine doğrudan erişime kıyasla).
Bu gerilemelerin etkisini azaltmak için uygulamalar, veri kopyalama işlemini azaltmak amacıyla birleştirme özelliğini kullanabilir ve alt dosya sistemi dosyalarına doğrudan erişmek için ContentProvider API'yi kullanabilir. Bu ve diğer optimizasyonlar ile bile, FUSE kullanıldığında okuma ve yazma işlemleri alt dosya sistemine doğrudan erişime kıyasla daha düşük bant genişliği görebilir — özellikle önbelleğe alma veya önceden okumanın yardımcı olamayacağı rastgele okuma işlemlerinde. Ayrıca, eski /sdcard/
yolu üzerinden depolamaya doğrudan erişen uygulamalarda, özellikle IO yoğun işlemler gerçekleştirirken belirgin performans düşüşleri yaşanmaya devam ediyor.
SDcardFS kullanıcı alanı istekleri
SDcardFS kullanmak, kullanıcı alanı çağrısını çekirdekten kaldırarak FUSE'in depolama alanı emülasyonunu ve izin kontrollerini hızlandırabilir. Kullanıcı alanı istekleri şu yolu izler: Kullanıcı alanı → VFS → sdcardfs → VFS → ext4 → Sayfa önbelleği/Depolama alanı.
Şekil 1. SDcardFS kullanıcı alanı istekleri
FUSE kullanıcı alanı istekleri
FUSE başlangıçta depolama alanı emülasyonunu etkinleştirmek ve uygulamaların dahili depolama alanını veya harici SD kartı şeffaf bir şekilde kullanmasına izin vermek için kullanılıyordu. Her kullanıcı alanı isteği şu yolu izlediğinden FUSE'yi kullanmak bazı ek maliyetler getirir: Kullanıcı alanı → VFS → FUSE sürücüsü → FUSE daemon'ı → VFS → ext4 → Sayfa önbelleği/Depolama alanı.
Şekil 2. FUSE kullanıcı alanı istekleri
FUSE geçiş istekleri
Dosya erişim izinlerinin çoğu, dosya açıldığında kontrol edilir. Bu dosyada okuma ve yazma işlemi yapılırken ek izin kontrolleri de gerçekleşir. Bazı durumlarda, dosya açıldığında istek yapan uygulamanın istenen dosyaya tam erişimi olduğu bilinebilir. Bu durumda sistemin, FUSE sürücüsünden FUSE daemon'a okuma ve yazma isteklerini iletmeye devam etmesine gerek yoktur (bu işlem yalnızca verileri bir yerden başka bir yere taşır).
FUSE geçişi sayesinde, açık bir isteği işleyen FUSE daemon'ı, FUSE sürücüsünü işleme izin verildiği ve sonraki tüm okuma ve yazma isteklerinin doğrudan alt dosya sistemine yönlendirilebileceği konusunda bilgilendirebilir. Bu sayede, kullanıcı alanı FUSE daemon'ının FUSE sürücü isteklerini yanıtlamasını beklemeyle ilgili ek yükü önleyebilirsiniz.
FUSE ve FUSE geçiş isteklerinin karşılaştırması aşağıda gösterilmiştir.
Şekil 3. FUSE isteği ve FUSE geçiş isteği
Bir uygulama FUSE dosya sistemi erişimi gerçekleştirdiğinde aşağıdaki işlemler gerçekleşir:
FUSE sürücüsü, isteği işler ve sıraya ekler, ardından
/dev/fuse
dosyasındaki belirli bir bağlantı örneği aracılığıyla bu FUSE dosya sistemini işleyen FUSE daemon'a sunar. FUSE daemon'ın okuması engellenir.FUSE daemon'ı bir dosyayı açma isteği aldığında, FUSE geçişinin söz konusu dosya için kullanılıp kullanılamayacağına karar verir. Mevcutsa daemon:
FUSE sürücüsünü bu istek hakkında bilgilendirir.
Açılan
/dev/fuse
dosyasının dosya tanımlayıcısında yapılması gerekenFUSE_DEV_IOC_PASSTHROUGH_OPEN
ioctl'u kullanarak dosya için FUSE geçişini etkinleştirir.
ioctl, aşağıdakileri içeren bir veri yapısı alır (parametre olarak):
Geçiş özelliğinin hedefi olan alt dosya sisteminin dosya tanımlayıcısı.
Şu anda işlenen FUSE isteğinin benzersiz tanımlayıcısı (açık veya oluştur ve aç olmalıdır).
Boş bırakılabilecek ve gelecekteki uygulamalar için tasarlanmış ek alanlar.
ioctl başarılı olursa FUSE daemon'ı, açık isteği tamamlar, FUSE sürücüsü FUSE daemon yanıtını işler ve çekirdekteki FUSE dosyasına alt dosya sistemi dosyasına referans eklenir. Bir uygulama FUSE dosyasında okuma/yazma işlemi istediğinde FUSE sürücüsü, daha alt bir dosya sistemine ait dosyaya referansın olup olmadığını kontrol eder.
Referans varsa sürücü, alt dosya sistemini hedefleyen aynı parametrelerle yeni bir sanal dosya sistemi (VFS) isteği oluşturur.
Referans yoksa sürücü isteği FUSE daemon'ına yönlendirir.
Yukarıdaki işlemler, genel dosyalarda okuma/yazma ve iterasyonlu okuma/yazma ve bellek haritalı dosyalarda okuma/yazma işlemleri için gerçekleşir. Belirli bir dosya için FUSE geçişi, söz konusu dosya kapatılana kadar mevcuttur.
FUSE geçişini uygulama
Android 12 çalıştıran cihazlarda FUSE geçişini etkinleştirmek için hedef cihazın $ANDROID_BUILD_TOP/device/…/device.mk
dosyasına aşağıdaki satırları ekleyin.
# Use FUSE passthrough
PRODUCT_PRODUCT_PROPERTIES += \
persist.sys.fuse.passthrough.enable=true
FUSE geçişini devre dışı bırakmak için yukarıdaki yapılandırma değişikliğini atlayın veya persist.sys.fuse.passthrough.enable
değerini false
olarak ayarlayın. Daha önce FUSE geçişini etkinleştirdiyseniz devre dışı bıraktığınızda cihaz FUSE geçişini kullanamaz ancak çalışmaya devam eder.
Cihazı flaşlamadan FUSE geçişini etkinleştirmek/devre dışı bırakmak için ADB komutlarını kullanarak sistem özelliğini değiştirin. Aşağıda bir örnek verilmiştir.
adb root
adb shell setprop persist.sys.fuse.passthrough.enable {true,false}
adb reboot
Daha fazla yardım için referans uygulamaya bakın.
FUSE geçişini doğrulama
MediaProvider'ın FUSE geçişini kullandığını doğrulamak için hata ayıklama mesajları için logcat
seçeneğini işaretleyin. Örnek:
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...
Günlükteki FuseDaemon: Using FUSE passthrough
girişi, FUSE geçişinin kullanıldığını gösterir.
Android 12 CTS, FUSE geçişini tetikleyen testleri içeren CtsStorageTest
'ü içerir. Testi manuel olarak çalıştırmak için aşağıdaki gibi bir test kullanın:
atest CtsStorageTest