FUSE geçişi

Android 12, FUSE geçişini destekler. Bu sayede, FUSE ek yükü en aza indirilerek alt dosya sistemine doğrudan erişime benzer bir performans elde edilir. FUSE geçişi android12-5.4, android12-5.10 ve android-mainline (yalnızca test) çekirdeklerinde desteklenir. Bu nedenle, bu özelliğin desteği cihazın kullandığı çekirdeğe ve cihazda çalışan Android sürümüne bağlıdır:

  • Android 11'den Android 12'ye yükseltme yapan cihazlar, bu cihazların çekirdekleri dondurulmuş olduğundan ve FUSE geçiş değişiklikleriyle resmi olarak yükseltilmiş bir çekirdeğe geçemediklerinden FUSE geçişini destekleyemez.

  • Android 12 ile kullanıma sunulan cihazlar, resmi çekirdek kullanıldığında FUSE geçişini destekleyebilir. Bu tür cihazlarda, FUSE geçişini uygulayan Android çerçeve kodu, otomatik olarak yükseltilen MediaProvider ana modülüne yerleştirilir. MediaProvider'ı ana hat modülü olarak uygulamayan cihazlar (ör. Android Go cihazlar) da herkese açık olarak paylaşıldığı için MediaProvider değişikliklerine erişebilir.

FUSE ve SDCardFS karşılaştırması

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ı programına (FUSE arka plan programı) yaptırılmasına olanak tanıyan bir mekanizmadır. Bu program, işlemleri uygular. Android 11, SDCardFS'yi kullanımdan kaldırdı ve depolama alanı emülasyonu için varsayılan çözüm olarak FUSE'u belirledi. Bu değişiklik kapsamında Android, dosya erişimlerini engellemek, ek güvenlik ve gizlilik özelliklerini zorunlu kılmak ve dosyaları çalışma zamanında değiştirmek için kendi FUSE daemon'unu uyguladı.

FUSE, sayfalar veya özellikler gibi önbelleğe alınabilir bilgilerle çalışırken iyi performans gösterse de özellikle orta ve düşük seviye cihazlarda belirgin olan harici depolama alanına erişirken performans düşüşlerine neden olur. Bu gerilemelere, FUSE dosya sisteminin uygulanmasında işbirliği yapan bir bileşen zincirinin yanı sıra FUSE sürücüsü ile FUSE daemon'u arasındaki iletişimde çekirdek alanından kullanıcı alanına yapılan birden fazla geçiş neden olur (daha yalın ve tamamen çekirdekte uygulanan alt dosya sistemine doğrudan erişimle karşılaştırıldığında).

Uygulamalar, bu gerilemeleri azaltmak için birleştirme özelliğini kullanarak veri kopyalamayı azaltabilir ve ContentProvider API'yi kullanarak daha düşük dosya sistemi dosyalarına doğrudan erişebilir. Bu ve diğer optimizasyonlara rağmen, FUSE kullanılırken okuma ve yazma işlemlerinde, özellikle rastgele okuma işlemlerinde (önbelleğe alma veya önceden okuma işlemlerinin yardımcı olamayacağı durumlarda) alt dosya sistemine doğrudan erişime kıyasla bant genişliği azalabilir. Ayrıca, depolamaya doğrudan eski /sdcard/ yoluyla erişen uygulamalarda, özellikle G/Ç yoğun işlemler gerçekleştirilirken 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'un depolama 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.

FUSE Geçişi SDcardFS

1. şekil. SDcardFS kullanıcı alanı istekleri

FUSE kullanıcı alanı istekleri

FUSE, başlangıçta depolama emülasyonunu etkinleştirmek ve uygulamaların dahili depolama alanını veya harici bir SD kartı şeffaf bir şekilde kullanmasına izin vermek için kullanılıyordu. FUSE kullanıldığında, her kullanıcı alanı isteği şu yolu izlediğinden ek yük oluşur: Kullanıcı alanı → VFS → FUSE sürücüsü → FUSE arka plan programı → VFS → ext4 → Sayfa önbelleği/Depolama.

FUSE Geçişi

Şekil 2. FUSE kullanıcı alanı istekleri

FUSE geçiş istekleri

Çoğu dosya erişim izni, dosya açılırken kontrol edilir. Dosyadan okuma ve dosyaya yazma sırasında ek izin kontrolleri yapılır. Bazı durumlarda, dosya açılırken istekte bulunan uygulamanın istenen dosyaya tam erişimi olduğu bilinebilir. Bu nedenle, sistemin FUSE sürücüsünden gelen okuma ve yazma isteklerini FUSE daemon'a yönlendirmeye devam etmesi gerekmez (çünkü bu yalnızca verileri bir yerden başka bir yere taşır).

FUSE geçişi ile açık bir isteği işleyen FUSE daemon'u, işlemin izin verildiğini ve sonraki tüm okuma ve yazma isteklerinin doğrudan alt dosya sistemine iletilebileceğini FUSE sürücüsüne bildirebilir. Bu sayede, kullanıcı alanı FUSE daemon'unun FUSE sürücüsü isteklerine yanıt vermesini beklemekten kaynaklanan ek yük önlenir.

FUSE ve FUSE geçiş isteklerinin karşılaştırması aşağıda gösterilmiştir.

FUSE Geçiş Karşılaştırması

3.Şekil 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:

  1. FUSE sürücüsü isteği işleyip sıraya alır, ardından FUSE dosya sistemini /dev/fuse dosyasındaki belirli bir bağlantı örneği üzerinden işleyen FUSE daemon'ına sunar. FUSE daemon'ın bu dosyayı okuması engellenir.

  2. FUSE daemon'ı bir dosyayı açma isteği aldığında, bu dosya için FUSE geçişinin kullanılabilir olup olmayacağına karar verir. Kullanılabiliyorsa daemon:

    1. FUSE sürücüsünü bu istek hakkında bilgilendirir.

    2. Açılan /dev/fuse dosyasının dosya tanımlayıcısında gerçekleştirilmesi gereken FUSE_DEV_IOC_PASSTHROUGH_OPEN ioctl kullanılarak dosya için FUSE geçişini etkinleştirir.

  3. ioctl, aşağıdaki öğeleri içeren bir veri yapısını (parametre olarak) alır:

    • Geçiş özelliğinin hedefi olan alt dosya sistemi dosyasının dosya tanımlayıcısı.

    • Şu anda işlenmekte olan FUSE isteğinin benzersiz tanımlayıcısı (açık olmalı veya oluşturulup açılmalıdır).

    • Boş bırakılabilen ve gelecekteki uygulamalar için tasarlanmış ek alanlar.

  4. ioctl başarılı olursa FUSE daemon, open isteğini tamamlar, FUSE sürücüsü FUSE daemon yanıtını işler ve çekirdekteki FUSE dosyasına alt dosya sistemi dosyasına yönelik bir referans eklenir. Bir uygulama, FUSE dosyasında okuma/yazma işlemi istediğinde FUSE sürücüsü, daha düşük bir dosya sistemi dosyasına yapılan referansın kullanılabilir olup olmadığını kontrol eder.

    • Bir referans varsa sürücü, aynı parametrelerle daha düşük dosya sistemi dosyasını hedefleyen 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 okuma-iter/yazma-iter için, belleğe eşlenmiş dosyalarda ise okuma/yazma işlemleri için gerçekleşir. Belirli bir dosya için FUSE geçişi, dosya kapatılana kadar devam eder.

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ırakmak cihazın FUSE geçişini kullanmasını engeller ancak cihaz işlevsel kalır.

Cihazı flashlamadan 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 gösterilmektedir.

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'yı kontrol edin. Örneğin:

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 öğesini içerir. Testi manuel olarak çalıştırmak için aşağıdaki örnekte gösterildiği gibi atest komutunu kullanın:

atest CtsStorageTest