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 → حافظه پنهان/ذخیرهسازی صفحه.
شکل 1. درخواست های فضای کاربر SDcardFS
FUSE درخواستهای فضای کاربر
FUSE در ابتدا برای فعال کردن شبیهسازی فضای ذخیرهسازی و اجازه دادن به برنامهها برای استفاده شفاف از حافظه داخلی یا کارت SD خارجی استفاده شد. استفاده از FUSE مقداری سربار را معرفی می کند زیرا هر درخواست فضای کاربر مسیر را دنبال می کند: فضای کاربری → VFS → درایور FUSE → دیمون FUSE → VFS → ext4 → کش صفحه/ذخیره سازی.
شکل 2. FUSE درخواست فضای کاربر
درخواست های عبور فیوز
اکثر مجوزهای دسترسی به فایل در زمان باز بودن فایل بررسی میشوند، با بررسی مجوزهای اضافی هنگام خواندن و نوشتن روی آن فایل انجام میشود. در برخی موارد، ممکن است در زمان باز شدن فایل بدانیم که برنامه درخواستکننده به فایل درخواستی دسترسی کامل دارد، بنابراین سیستم نیازی به ادامه ارسال درخواستهای خواندن و نوشتن از درایور FUSE به شبح FUSE ندارد (به عنوان مثال فقط داده ها را از یک مکان به مکان دیگر منتقل می کند).
با عبور FUSE، شبح FUSE که یک درخواست باز را مدیریت میکند، میتواند به درایور FUSE اطلاع دهد که عملیات مجاز است و تمام درخواستهای خواندن و نوشتن بعدی میتوانند مستقیماً به سیستم فایل پایینتر ارسال شوند. با این کار از سربار اضافی انتظار برای پاسخ دادن به درخواستهای درایور FUSE توسط دیمون فضای کاربر FUSE جلوگیری میشود.
مقایسه درخواست های عبور FUSE و FUSE در زیر نشان داده شده است.
شکل 3. درخواست FUSE در مقابل درخواست عبور FUSE
هنگامی که یک برنامه دسترسی به سیستم فایل FUSE را انجام می دهد، عملیات زیر رخ می دهد:
درایور FUSE درخواست را مدیریت می کند و در صف قرار می دهد، سپس آن را به شبح FUSE ارائه می دهد که سیستم فایل FUSE را از طریق یک نمونه اتصال خاص در فایل
/dev/fuse
که کنترل می کند، که شبح FUSE از خواندن آن جلوگیری می کند.هنگامی که شبح FUSE درخواستی برای باز کردن یک فایل دریافت می کند، تصمیم می گیرد که آیا عبور FUSE برای آن فایل خاص در دسترس باشد یا خیر. اگر در دسترس است، دیمون:
درایور FUSE را در مورد این درخواست مطلع می کند.
عبور FUSE را برای فایل با استفاده از
FUSE_DEV_IOC_PASSTHROUGH_OPEN
ioctl فعال میکند، که باید روی توصیفگر فایل باز شده/dev/fuse
انجام شود.
ioctl (به عنوان یک پارامتر) ساختار داده ای را دریافت می کند که شامل موارد زیر است:
توصیف کننده فایل فایل سیستم فایل پایینی که هدف ویژگی عبور است.
شناسه منحصر به فرد درخواست FUSE که در حال حاضر در حال رسیدگی است (باید باز یا ایجاد و باز شود).
فیلدهای اضافی را می توان خالی گذاشت و برای پیاده سازی های بعدی در نظر گرفته شده است.
اگر 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