FUSE पासथ्रू

Android 12 में FUSE पासथ्रू की सुविधा काम करती है. इससे, FUSE के ओवरहेड को कम किया जाता है, ताकि निचले फ़ाइल सिस्टम को सीधे ऐक्सेस करने जैसी परफ़ॉर्मेंस मिल सके. FUSE पासथ्रू की सुविधा, android12-5.4, android12-5.10, और android-mainline (सिर्फ़ टेस्टिंग के लिए) कर्नेल में काम करती है. इसका मतलब है कि इस सुविधा के काम करने की सुविधा, डिवाइस में इस्तेमाल किए जा रहे कर्नेल और डिवाइस पर चल रहे Android वर्शन पर निर्भर करती है:

  • Android 11 से Android 12 पर अपग्रेड करने वाले डिवाइसों पर, FUSE पासथ्रू की सुविधा काम नहीं करेगी. ऐसा इसलिए, क्योंकि इन डिवाइसों के लिए कर्नेल फ़्रीज़ किए गए हैं और इन्हें ऐसे कर्नेल पर नहीं ले जाया जा सकता जिसे FUSE पासथ्रू में हुए बदलावों के साथ आधिकारिक तौर पर अपग्रेड किया गया हो.

  • Android 12 के साथ लॉन्च होने वाले डिवाइसों पर, आधिकारिक कर्नेल का इस्तेमाल करने पर, FUSE पासथ्रू की सुविधा काम कर सकती है. ऐसे डिवाइसों के लिए, FUSE पासथ्रू को लागू करने वाला Android फ़्रेमवर्क कोड, MediaProvider के मुख्य मॉड्यूल में एम्बेड होता है. यह मॉड्यूल अपने-आप अपग्रेड हो जाता है. MediaProvider को मुख्य मॉड्यूल के तौर पर लागू न करने वाले डिवाइस (उदाहरण के लिए, Android Go डिवाइस), MediaProvider में किए गए बदलावों को भी ऐक्सेस कर सकते हैं. ऐसा इसलिए, क्योंकि ये बदलाव सार्वजनिक तौर पर शेयर किए जाते हैं.

FUSE बनाम SDCardFS

यूज़रस्पेस में फ़ाइल सिस्टम (FUSE) एक ऐसा तरीका है जिसकी मदद से, FUSE फ़ाइल सिस्टम पर किए जाने वाले ऑपरेशन को कर्नेल (FUSE ड्राइवर) से यूज़रस्पेस प्रोग्राम (FUSE डेमन) को आउटसोर्स किया जा सकता है. यह प्रोग्राम, ऑपरेशन को लागू करता है. Android 11 में SDCardFS का इस्तेमाल बंद कर दिया गया है. साथ ही, स्टोरेज को एमुलेट करने के लिए, FUSE को डिफ़ॉल्ट समाधान बनाया गया है. इस बदलाव के तहत, Android ने अपना FUSE डेमन लागू किया है. इससे फ़ाइल ऐक्सेस को इंटरसेप्ट करने, ज़्यादा सुरक्षा और निजता से जुड़ी सुविधाओं को लागू करने, और रनटाइम के दौरान फ़ाइलों में बदलाव करने में मदद मिलती है.

पेजों या एट्रिब्यूट जैसी कैश मेमोरी में सेव की जा सकने वाली जानकारी के साथ काम करते समय, FUSE अच्छा परफ़ॉर्म करता है. हालांकि, बाहरी स्टोरेज को ऐक्सेस करते समय, यह परफ़ॉर्मेंस में गिरावट लाता है. यह गिरावट, खास तौर पर मिड और लो-एंड डिवाइसों में दिखती है. ये रेग्रेसन, FUSE फ़ाइल सिस्टम को लागू करने में मदद करने वाले कॉम्पोनेंट की चेन की वजह से होते हैं. साथ ही, FUSE ड्राइवर और FUSE डेमन के बीच कम्यूनिकेशन में, केरनल स्पेस से यूज़र स्पेस में कई स्विच होने की वजह से भी ये रेग्रेसन होते हैं. यह कम्यूनिकेशन, लोअर फ़ाइल सिस्टम के सीधे ऐक्सेस की तुलना में ज़्यादा धीमा होता है.

इन समस्याओं को कम करने के लिए, ऐप्लिकेशन स्प्लिसिंग का इस्तेमाल करके, डेटा कॉपी करने की प्रोसेस को कम कर सकते हैं. साथ ही, ContentProvider API का इस्तेमाल करके, निचले फ़ाइल सिस्टम की फ़ाइलों को सीधे ऐक्सेस कर सकते हैं. इन और अन्य ऑप्टिमाइज़ेशन के बावजूद, हो सकता है कि FUSE का इस्तेमाल करने पर, पढ़ने और लिखने के ऑपरेशन के लिए कम बैंडविड्थ मिले. यह बैंडविड्थ, निचले फ़ाइल सिस्टम के सीधे ऐक्सेस की तुलना में कम हो सकती है — खास तौर पर, रैंडम रीड ऑपरेशन के लिए, जहां कैश मेमोरी या पहले से पढ़ने की सुविधा काम नहीं आती. साथ ही, ऐसे ऐप्लिकेशन जिनमें स्टोरेज को सीधे /sdcard/ पाथ के ज़रिए ऐक्सेस किया जाता है उनकी परफ़ॉर्मेंस में काफ़ी गिरावट आती है. खास तौर पर, ज़्यादा आईओ वाले ऑपरेशन करते समय.

SDcardFS के उपयोगकर्ता स्पेस से जुड़े अनुरोध

SDcardFS का इस्तेमाल करने से, स्टोरेज इम्यूलेशन और FUSE की अनुमति की जांच की प्रोसेस तेज़ हो सकती है. ऐसा, कर्नेल से उपयोगकर्ता स्पेस कॉल को हटाकर किया जा सकता है. यूज़रस्पेस के अनुरोध, इस पाथ पर चलते हैं: यूज़रस्पेस → VFS → sdcardfs → VFS → ext4 → पेज कैश/स्टोरेज.

FUSE Passthrough SDcardFS

पहली इमेज. SDcardFS के उपयोगकर्ता स्पेस से जुड़े अनुरोध

FUSE यूज़रस्पेस के अनुरोध

FUSE का इस्तेमाल शुरुआत में स्टोरेज इम्यूलेशन की सुविधा चालू करने के लिए किया जाता था. साथ ही, इससे ऐप्लिकेशन को डिवाइस के इंटरनल स्टोरेज या बाहरी एसडी कार्ड का इस्तेमाल साफ़ तौर पर करने की अनुमति मिलती थी. FUSE का इस्तेमाल करने पर, कुछ ओवरहेड होता है. ऐसा इसलिए होता है, क्योंकि उपयोगकर्ता स्पेस का हर अनुरोध इस पाथ का पालन करता है: उपयोगकर्ता स्पेस → VFS → FUSE ड्राइवर → FUSE डेमन → VFS → ext4 → पेज कैश/स्टोरेज.

FUSE Passthrough FUSE

दूसरी इमेज. FUSE यूज़रस्पेस के अनुरोध

FUSE पासथ्रू अनुरोध

फ़ाइल को खोलने के समय, ज़्यादातर फ़ाइल ऐक्सेस की अनुमतियों की जांच की जाती है. साथ ही, उस फ़ाइल को पढ़ने और उसमें बदलाव करने के दौरान, अनुमतियों की अन्य जांच की जाती है. कुछ मामलों में, फ़ाइल खोलने के समय यह पता चल सकता है कि अनुरोध करने वाले ऐप्लिकेशन के पास अनुरोध की गई फ़ाइल का पूरा ऐक्सेस है. इसलिए, सिस्टम को FUSE ड्राइवर से FUSE डेमन को अनुरोधों को पढ़ने और लिखने के लिए फ़ॉरवर्ड करना जारी रखने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि इससे सिर्फ़ डेटा को एक जगह से दूसरी जगह ले जाया जाएगा.

FUSE पासथ्रू की मदद से, किसी खुले अनुरोध को मैनेज करने वाला FUSE डेमन, FUSE ड्राइवर को सूचना दे सकता है कि कार्रवाई की अनुमति है और इसके बाद, पढ़ने और लिखने के सभी अनुरोधों को सीधे निचले फ़ाइल सिस्टम पर भेजा जा सकता है. इससे, FUSE ड्राइवर के अनुरोधों का जवाब देने के लिए, यूज़र स्पेस FUSE डेमन के इंतज़ार करने से जुड़ी अतिरिक्त समस्या से बचा जा सकता है.

FUSE और FUSE पासथ्रू अनुरोधों की तुलना यहां दी गई है.

FUSE पास-थ्रू की तुलना

तीसरी इमेज. FUSE अनुरोध बनाम FUSE पासथ्रू अनुरोध

जब कोई ऐप्लिकेशन FUSE फ़ाइल सिस्टम को ऐक्सेस करता है, तो ये कार्रवाइयां होती हैं:

  1. FUSE ड्राइवर, अनुरोध को मैनेज करता है और उसे सूची में जोड़ता है. इसके बाद, उसे FUSE डेमॉन को दिखाता है. यह डेमॉन, /dev/fuse फ़ाइल पर किसी खास कनेक्शन इंस्टेंस के ज़रिए उस FUSE फ़ाइल सिस्टम को मैनेज करता है जिसे FUSE डेमॉन पढ़ने से ब्लॉक किया गया है.

  2. जब FUSE डेमन को कोई फ़ाइल खोलने का अनुरोध मिलता है, तो वह यह तय करता है कि उस फ़ाइल के लिए FUSE पासथ्रू उपलब्ध होना चाहिए या नहीं. अगर यह उपलब्ध है, तो डीमन:

    1. इस अनुरोध के बारे में FUSE ड्राइवर को सूचना देता है.

    2. FUSE_DEV_IOC_PASSTHROUGH_OPEN ioctl का इस्तेमाल करके, फ़ाइल के लिए FUSE पासथ्रू की सुविधा चालू करता है. इसे खोले गए /dev/fuse के फ़ाइल डिस्क्रिप्टर पर किया जाना चाहिए.

  3. ioctl को पैरामीटर के तौर पर एक डेटा स्ट्रक्चर मिलता है, जिसमें ये शामिल होते हैं:

    • पासथ्रू सुविधा के टारगेट के तौर पर इस्तेमाल की जाने वाली, लोअर फ़ाइल सिस्टम फ़ाइल का फ़ाइल डिस्क्रिप्टर.

    • फ़िलहाल प्रोसेस किए जा रहे FUSE अनुरोध का यूनीक आइडेंटिफ़ायर (यह खुला होना चाहिए या बनाएं और खोलें).

    • अतिरिक्त फ़ील्ड, जिन्हें खाली छोड़ा जा सकता है और जिन्हें आने वाले समय में लागू किया जाएगा.

  4. अगर ioctl काम करता है, तो FUSE डेमन, फ़ाइल खोलने का अनुरोध पूरा करता है. साथ ही, FUSE ड्राइवर, FUSE डेमन के जवाब को मैनेज करता है. इसके बाद, कर्नेल में मौजूद FUSE फ़ाइल में, लोअर फ़ाइल सिस्टम फ़ाइल का रेफ़रंस जोड़ा जाता है. जब कोई ऐप्लिकेशन, FUSE फ़ाइल पर पढ़ने/लिखने का अनुरोध करता है, तो FUSE ड्राइवर यह जांच करता है कि किसी निचले फ़ाइल सिस्टम फ़ाइल का रेफ़रंस उपलब्ध है या नहीं.

    • अगर कोई रेफ़रंस उपलब्ध है, तो ड्राइवर, निचले फ़ाइल सिस्टम फ़ाइल को टारगेट करने वाले उन ही पैरामीटर के साथ एक नया वर्चुअल फ़ाइल सिस्टम (वीएफ़एस) अनुरोध बनाता है.

    • अगर कोई रेफ़रंस उपलब्ध नहीं है, तो ड्राइवर अनुरोध को FUSE डिमन को भेजता है.

ऊपर बताए गए ऑपरेशन, सामान्य फ़ाइलों पर read/write और read-iter/write-iter के लिए होते हैं. साथ ही, मेमोरी-मapped फ़ाइलों पर read/write ऑपरेशन के लिए भी होते हैं. किसी फ़ाइल के लिए FUSE पासथ्रू तब तक मौजूद रहता है, जब तक वह फ़ाइल बंद नहीं हो जाती.

FUSE पासथ्रू लागू करना

Android 12 पर काम करने वाले डिवाइसों पर FUSE पासथ्रू को चालू करने के लिए, टारगेट किए गए डिवाइस की $ANDROID_BUILD_TOP/device/…/device.mk फ़ाइल में ये लाइनें जोड़ें.

# Use FUSE passthrough
PRODUCT_PRODUCT_PROPERTIES += \
    persist.sys.fuse.passthrough.enable=true

FUSE पासथ्रू को बंद करने के लिए, ऊपर दिए गए कॉन्फ़िगरेशन में बदलाव न करें या persist.sys.fuse.passthrough.enable को false पर सेट करें. अगर आपने पहले से ही FUSE पासथ्रू की सुविधा चालू की हुई है, तो इसे बंद करने पर डिवाइस पर FUSE पासथ्रू की सुविधा का इस्तेमाल नहीं किया जा सकेगा. हालांकि, डिवाइस काम करता रहेगा.

डिवाइस को फ़्लैश किए बिना, FUSE पासथ्रू को चालू/बंद करने के लिए, ADB निर्देशों का इस्तेमाल करके सिस्टम प्रॉपर्टी बदलें. इसका उदाहरण नीचे दिया गया है.

adb root
adb shell setprop persist.sys.fuse.passthrough.enable {true,false}
adb reboot

ज़्यादा मदद पाने के लिए, रेफ़रंस लागू करने से जुड़ा लेख पढ़ें.

FUSE पासथ्रू की पुष्टि करना

यह पुष्टि करने के लिए कि MediaProvider, FUSE पासथ्रू का इस्तेमाल कर रहा है या नहीं, मैसेज डीबग करने के लिए logcat देखें. उदाहरण के लिए:

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...

लॉग में FuseDaemon: Using FUSE passthrough एंट्री से यह पक्का होता है कि FUSE पासथ्रू का इस्तेमाल किया जा रहा है.

Android 12 CTS में CtsStorageTest शामिल है. इसमें ऐसे टेस्ट शामिल हैं जो FUSE पासथ्रू को ट्रिगर करते हैं. मैन्युअल तरीके से टेस्ट चलाने के लिए, यहां दिए गए तरीके के मुताबिक, atest का इस्तेमाल करें:

atest CtsStorageTest