عبور فیوز

Android 12 از FUSE passthrough پشتیبانی می‌کند، که سربار FUSE را برای دستیابی به عملکردی قابل مقایسه با دسترسی مستقیم به سیستم فایل پایین‌تر به حداقل می‌رساند. عبور FUSE در هسته‌های android12-5.4 ، android12-5.10 و android-mainline (فقط آزمایشی) پشتیبانی می‌شود، به این معنی که پشتیبانی از این ویژگی به هسته مورد استفاده دستگاه و نسخه اندرویدی که دستگاه اجرا می‌کند بستگی دارد:

  • دستگاه‌هایی که از Android 11 به Android 12 ارتقا می‌یابند نمی‌توانند از FUSE passthrough پشتیبانی کنند، زیرا هسته‌های این دستگاه‌ها ثابت است و نمی‌توانند به هسته‌ای منتقل شوند که با تغییرات FUSE به طور رسمی ارتقا یافته است.

  • دستگاه‌هایی که با Android 12 راه‌اندازی می‌شوند می‌توانند هنگام استفاده از یک هسته رسمی از FUSE پشتیبانی کنند. برای چنین دستگاه‌هایی، کد فریمورک اندرویدی که عبور FUSE را پیاده‌سازی می‌کند، در ماژول خط اصلی MediaProvider تعبیه شده است که به‌طور خودکار ارتقا می‌یابد. دستگاه‌هایی که MediaProvider را به‌عنوان یک ماژول خط اصلی پیاده‌سازی نمی‌کنند (مثلاً دستگاه‌های Android Go)، می‌توانند به تغییرات MediaProvider که به صورت عمومی به اشتراک گذاشته می‌شوند نیز دسترسی داشته باشند.

FUSE در مقابل SDCardFS

سیستم فایل در فضای کاربری (FUSE) مکانیزمی است که به عملیات انجام شده در یک سیستم فایل FUSE اجازه می دهد تا توسط هسته (درایور FUSE) به یک برنامه فضای کاربر (FUSE daemon) برون سپاری شود که عملیات را اجرا می کند. اندروید 11 SDCardFS را منسوخ کرد و FUSE را به راه حل پیش فرض برای شبیه سازی فضای ذخیره سازی تبدیل کرد. به عنوان بخشی از این تغییر، اندروید دیمون FUSE خود را برای رهگیری دسترسی به فایل ها، اعمال ویژگی های امنیتی و حریم خصوصی اضافی و دستکاری فایل ها در زمان اجرا پیاده سازی کرد.

در حالی که FUSE هنگام برخورد با اطلاعات حافظه پنهان مانند صفحات یا ویژگی ها عملکرد خوبی دارد، رگرسیون های عملکرد را هنگام دسترسی به حافظه خارجی معرفی می کند که به ویژه در دستگاه های متوسط ​​و پایین قابل مشاهده است. این رگرسیون ها توسط زنجیره ای از مؤلفه ها در اجرای سیستم فایل FUSE و همچنین سوئیچ های متعدد از فضای هسته به فضای کاربر در ارتباطات بین درایور FUSE و شبح FUSE (در مقایسه با دسترسی مستقیم به فایل پایین تر) ایجاد می شود. سیستمی که لاغرتر است و به طور کامل در هسته پیاده سازی شده است).

برای کاهش این رگرسیون ها، برنامه ها می توانند از splicing برای کاهش کپی کردن داده ها استفاده کنند و از ContentProvider API برای دسترسی مستقیم به فایل های سیستم فایل پایین تر استفاده کنند. حتی با این بهینه‌سازی‌ها و سایر بهینه‌سازی‌ها ، عملیات خواندن و نوشتن ممکن است در مقایسه با دسترسی مستقیم به سیستم فایل پایین‌تر، پهنای باند کمتری را هنگام استفاده از FUSE مشاهده کنند - به خصوص با عملیات خواندن تصادفی، که در آن هیچ کش یا خواندن پیش‌خوان نمی‌تواند کمک کند. و برنامه‌هایی که مستقیماً از طریق مسیر قدیمی /sdcard/ به فضای ذخیره‌سازی دسترسی دارند، افت عملکرد قابل توجهی را تجربه می‌کنند، به‌ویژه هنگام انجام عملیات‌های فشرده IO.

درخواست‌های فضای کاربران 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 که یک درخواست باز را مدیریت می‌کند، می‌تواند به درایور FUSE اطلاع دهد که عملیات مجاز است و تمام درخواست‌های خواندن و نوشتن بعدی می‌توانند مستقیماً به سیستم فایل پایین‌تر ارسال شوند. با این کار از سربار اضافی انتظار برای پاسخ دادن به درخواست‌های درایور FUSE توسط دیمون فضای کاربر FUSE جلوگیری می‌شود.

مقایسه درخواست های عبور FUSE و FUSE در زیر نشان داده شده است.

FUSE Passthrough مقایسه

شکل 3. درخواست FUSE در مقابل درخواست عبور FUSE

هنگامی که یک برنامه دسترسی به سیستم فایل FUSE را انجام می دهد، عملیات زیر رخ می دهد:

  1. درایور FUSE درخواست را مدیریت می کند و در صف قرار می دهد، سپس آن را به شبح FUSE ارائه می دهد که سیستم فایل FUSE را از طریق یک نمونه اتصال خاص در فایل /dev/fuse که کنترل می کند، که شبح FUSE از خواندن آن جلوگیری می کند.

  2. هنگامی که شبح FUSE درخواستی برای باز کردن یک فایل دریافت می کند، تصمیم می گیرد که آیا عبور FUSE برای آن فایل خاص در دسترس باشد یا خیر. اگر در دسترس است، دیمون:

    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 برای یک فایل مشخص تا زمانی که آن فایل بسته نشود وجود دارد.

پیاده سازی FUSE passthrough

برای فعال کردن 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 می‌شود اما دستگاه همچنان کار می‌کند.

برای فعال/غیرفعال کردن FUSE passthrough بدون فلش دستگاه، ویژگی سیستم را با استفاده از دستورات 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 passthrough در حال استفاده است.

Android 12 CTS شامل CtsStorageTest می‌شود که شامل تست‌هایی است که FUSE را راه‌اندازی می‌کند. برای اجرای تست به صورت دستی، مطابق شکل زیر از atest استفاده کنید:

atest CtsStorageTest