تقنية مرور الإشارة في FUSE

يتوافق نظام التشغيل Android 12 مع ميزة FUSE passthrough التي تقلّل من حِمل FUSE لتحقيق أداء مماثل للأداء عند الوصول المباشر إلى نظام الملفات الأدنى. تتوفّر ميزة تمرير FUSE في نواة android12-5.4 وandroid12-5.10 وandroid-mainline (للاختبار فقط)، ما يعني أنّ توفّر هذه الميزة يعتمد على النواة التي يستخدمها الجهاز وإصدار Android الذي يعمل به الجهاز:

  • لا يمكن للأجهزة التي تتم ترقيتها من Android 11 إلى Android 12 أن تتوافق مع ميزة "نقل بيانات FUSE" لأنّ نوى هذه الأجهزة ثابتة ولا يمكنها الانتقال إلى نواة تمت ترقيتها رسميًا مع تغييرات ميزة "نقل بيانات FUSE".

  • يمكن للأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android أن تتيح نقل بيانات FUSE عند استخدام نواة رسمية. بالنسبة إلى هذه الأجهزة، يتم تضمين رمز إطار عمل Android الذي ينفّذ ميزة FUSE passthrough في وحدة MediaProvider الرئيسية، والتي تتم ترقيتها تلقائيًا. يمكن أيضًا للأجهزة التي لا تستخدم MediaProvider كوحدة رئيسية (على سبيل المثال، أجهزة Android Go) الوصول إلى تغييرات MediaProvider عند مشاركتها بشكل علني.

FUSE مقابل SDCardFS

نظام الملفات في مساحة المستخدم (FUSE) هو آلية تتيح للعمليات التي يتم تنفيذها على نظام ملفات FUSE أن يتم الاستعانة بمصادر خارجية لتنفيذها من خلال النواة (برنامج تشغيل FUSE) إلى برنامج في مساحة المستخدم (برنامج FUSE الخفي)، والذي ينفذ العمليات. في نظام التشغيل Android 11، تم إيقاف SDCardFS نهائيًا وأصبح FUSE هو الحل التلقائي لمحاكاة مساحة التخزين. وكجزء من هذا التغيير، نفّذ نظام التشغيل Android برنامج FUSE الخاص به لاعتراض عمليات الوصول إلى الملفات، وفرض ميزات إضافية للأمان والخصوصية، ومعالجة الملفات أثناء وقت التشغيل.

على الرغم من أنّ نظام FUSE يحقّق أداءً جيدًا عند التعامل مع المعلومات القابلة للتخزين المؤقت، مثل الصفحات أو السمات، إلا أنّه يؤدي إلى تراجع الأداء عند الوصول إلى وحدة التخزين الخارجية، وهو ما يظهر بشكل خاص في الأجهزة المتوسطة والمنخفضة المواصفات. تحدث هذه المشاكل بسبب سلسلة من المكوّنات التي تتعاون في تنفيذ نظام ملفات FUSE، بالإضافة إلى عمليات تبديل متعددة من مساحة kernel إلى مساحة المستخدم في عمليات الاتصال بين برنامج تشغيل FUSE وخدمة FUSE (مقارنةً بالوصول المباشر إلى نظام الملفات الأدنى الذي يكون أكثر بساطة ويتم تنفيذه بالكامل في kernel).

للتخفيف من حدة هذه المشاكل، يمكن للتطبيقات استخدام التقطيع لتقليل نسخ البيانات واستخدام ContentProvider API للوصول مباشرةً إلى ملفات نظام الملفات الأدنى. وحتى مع هذه التحسينات وغيرها، قد تنخفض سرعة نقل البيانات في عمليات القراءة والكتابة عند استخدام FUSE مقارنةً بالوصول المباشر إلى نظام الملفات الأساسي، خاصةً مع عمليات القراءة العشوائية التي لا يمكن فيها الاستفادة من التخزين المؤقت أو القراءة المسبقة. وستستمر التطبيقات التي تصل إلى مساحة التخزين مباشرةً من خلال مسار /sdcard/ القديم في مواجهة انخفاضات ملحوظة في الأداء، خاصةً عند تنفيذ عمليات تتطلّب معدل نقل بيانات مرتفعًا.

طلبات مساحة المستخدم في SDcardFS

يمكن أن يؤدي استخدام SDcardFS إلى تسريع محاكاة التخزين وعمليات التحقّق من الأذونات في FUSE من خلال إزالة طلب مساحة المستخدم من النواة. تتّبع طلبات مساحة المستخدم المسار التالي: مساحة المستخدم → نظام الملفات الافتراضي (VFS) → نظام الملفات sdcardfs → نظام الملفات الافتراضي (VFS) → نظام الملفات ext4 → ذاكرة التخزين المؤقت للصفحة/مساحة التخزين.

FUSE Passthrough SDcardFS

الشكل 1. طلبات مساحة المستخدم في SDcardFS

طلبات مساحة المستخدم في FUSE

تم استخدام FUSE في البداية لتفعيل محاكاة مساحة التخزين والسماح للتطبيقات باستخدام مساحة التخزين الداخلية أو بطاقة SD الخارجية بشكل شفاف. يؤدي استخدام FUSE إلى زيادة بعض النفقات العامة لأنّ كل طلب من مساحة المستخدمين يتّبع المسار التالي: مساحة المستخدمين → نظام الملفات الافتراضي (VFS) → برنامج تشغيل FUSE → برنامج FUSE الخفي → نظام الملفات الافتراضي (VFS) → ext4 → ذاكرة التخزين المؤقت للصفحات/مساحة التخزين.

FUSE Passthrough FUSE

الشكل 2. طلبات مساحة المستخدم في FUSE

طلبات تمرير FUSE

يتم التحقّق من معظم أذونات الوصول إلى الملفات عند فتح الملف، ويتم إجراء عمليات تحقّق إضافية من الأذونات عند القراءة من الملف والكتابة إليه. في بعض الحالات، يمكن معرفة أنّ التطبيق الذي يطلب الوصول لديه إذن كامل بالوصول إلى الملف المطلوب عند فتح الملف، وبالتالي لا يحتاج النظام إلى مواصلة إعادة توجيه طلبات القراءة والكتابة من برنامج تشغيل FUSE إلى برنامج FUSE الخفي (لأنّ ذلك سيؤدي فقط إلى نقل البيانات من مكان إلى آخر).

باستخدام ميزة FUSE passthrough، يمكن للبرنامج الخفي FUSE الذي يتعامل مع طلب مفتوح إعلام برنامج تشغيل FUSE بأنّ العملية مسموح بها وأنّه يمكن إعادة توجيه جميع طلبات القراءة والكتابة اللاحقة مباشرةً إلى نظام الملفات الأدنى. يساعد ذلك في تجنُّب الحمل الزائد الناتج عن انتظار ردّ برنامج FUSE الخفي في مساحة المستخدم على طلبات برنامج تشغيل FUSE.

في ما يلي مقارنة بين طلبات FUSE وطلبات FUSE passthrough.

مقارنة بين خيارات "مرور الإشارة" في FUSE

الشكل 3. طلب FUSE مقابل طلب FUSE passthrough

عندما ينفّذ تطبيق عملية وصول إلى نظام ملفات FUSE، تحدث العمليات التالية:

  1. يتعامل برنامج تشغيل FUSE مع الطلب ويضعه في قائمة الانتظار، ثم يعرضه على برنامج FUSE الخفي الذي يتعامل مع نظام ملفات FUSE من خلال مثيل اتصال معيّن على ملف /dev/fuse، والذي يتم حظر برنامج FUSE الخفي من قراءته.

  2. عندما يتلقّى برنامج FUSE الخفي طلبًا بفتح ملف، يقرّر ما إذا كان يجب أن تتوفّر ميزة FUSE passthrough لهذا الملف المعيّن. إذا كان متاحًا، سيفعل البرنامج الخفي ما يلي:

    1. يُعلم برنامج تشغيل FUSE بهذا الطلب.

    2. تتيح هذه السمة تمرير FUSE للملف باستخدام FUSE_DEV_IOC_PASSTHROUGH_OPEN ioctl، والذي يجب تنفيذه على واصف الملف الذي تم فتحه /dev/fuse.

  3. يتلقّى الأمر ioctl (كمَعلمة) بنية بيانات تحتوي على ما يلي:

    • واصف الملف الخاص بملف نظام الملفات الأدنى الذي يمثّل هدف ميزة النقل المباشر.

    • المعرّف الفريد لطلب FUSE الذي تتم معالجته حاليًا (يجب أن يكون مفتوحًا أو إنشاء وفتح).

    • حقول إضافية يمكن تركها فارغة وهي مخصّصة لعمليات التنفيذ المستقبلية.

  4. إذا نجح ioctl، يكمل البرنامج الخفي FUSE طلب الفتح، ويتعامل برنامج تشغيل FUSE مع رد البرنامج الخفي FUSE، وتتم إضافة مرجع إلى ملف نظام الملفات الأدنى إلى ملف FUSE داخل النواة. عندما يطلب تطبيق إجراء قراءة/كتابة على ملف FUSE، يتحقّق برنامج تشغيل FUSE مما إذا كان مرجع ملف نظام الملفات الأدنى متاحًا.

    • إذا كان هناك مرجع متاح، ينشئ برنامج التشغيل طلبًا جديدًا لنظام الملفات الافتراضي (VFS) يتضمّن المَعلمات نفسها التي تستهدف ملف نظام الملفات الأدنى.

    • إذا لم تكن المرجع متوفّرًا، يعيد برنامج التشغيل توجيه الطلب إلى برنامج FUSE الخفي.

تحدث العمليات المذكورة أعلاه للقراءة/الكتابة والقراءة/الكتابة بشكل متكرر على الملفات العامة، وعمليات القراءة/الكتابة على الملفات التي يتم ربطها بالذاكرة. تتوفّر ميزة FUSE passthrough لملف معيّن إلى أن يتم إغلاق هذا الملف.

تنفيذ ميزة "تمرير نظام الملفات في مساحة المستخدم" (FUSE)

لتفعيل ميزة FUSE passthrough على الأجهزة التي تعمل بنظام التشغيل Android 12، أضِف الأسطر التالية إلى ملف $ANDROID_BUILD_TOP/device/…/device.mk الخاص بالجهاز المستهدف.

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

لإيقاف ميزة FUSE passthrough، احذف تغيير الإعدادات أعلاه أو اضبط persist.sys.fuse.passthrough.enable على false. إذا سبق لك تفعيل ميزة FUSE passthrough، سيؤدي إيقافها إلى منع الجهاز من استخدامها، ولكن سيظل الجهاز يعمل.

لتفعيل/إيقاف ميزة FUSE passthrough بدون إعادة ضبط الجهاز، غيِّر خاصية النظام باستخدام أوامر ADB. يظهر مثال أدناه.

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

للحصول على مساعدة إضافية، يمكنك الرجوع إلى التنفيذ المرجعي.

التحقّق من صحة ميزة "نقل بيانات نظام الملفات في الفضاء الخاص بالمستخدم"

للتحقّق من أنّ 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.

تتضمّن مجموعة أدوات اختبار التوافق (CTS) لنظام التشغيل Android 12 CtsStorageTest، والتي تتضمّن اختبارات تؤدي إلى تفعيل ميزة "نقل البيانات عبر نظام الملفات في مساحة المستخدم" (FUSE). لتشغيل الاختبار يدويًا، استخدِم الأمر atest كما هو موضّح أدناه:

atest CtsStorageTest