Szóval utánanéztem egy kicsit a dolognak és én őszintén szólva nem látom igazán, hogy miben akadályoz a fuse apija. Egy tipikus (lokális blokkos eszközön lévő) filerendszer esetén három fő adatmozgatási probléma van. Az egyik, ami szorosan kapcsolódik a fuse apihoz hogy a write függvényen keresztül pointerrel kapott adattömböt hogyan is kapod meg, illetve a read függvényen keresztül hogyan adod vissza a tömböt. A másik jellegű probléma, hogy hogyan éred el a nyers eszközt, amin a filerendszer ténylegesen tárolva van. A harmadik, hogy maga a filerendszer implemnetáció meg tudja-e úszni memóriamásolás nélkül, hogy az eszközről kapott blokkot kiadja a read függvénnyel, illetve a write-tal kapott blokkot egy az egyben bele tudja-e mappelni az eszköz területére.
Egy akármilyen userspace program kérheti a kernelt, hogy mappeljen be neki egy filet memóriatartományba, az mmap pont erre való. Az, hogy utána a hozzáférések ténylegesen hogyan zajlanak, vagyis kell-e memóriamásolást végezni az device file-t biztosító filerendszer implementációjától függ. A /dev/hdX /dev/sdX jellegű blokkos eszközök esetén közvetlenül a hardver driver szolgálja ki a kéréseket. Az hogy használ-e dma-t a hardver és ha igen, a dma célpufferből kell-e másolgatni az a hardver driver belső magánügye. Tehát ezidáig én úgy látom, hogy a fuse és egy natív filerendszer driver között nincs érdemi különbség. Tény, hogy az mmap a page-ek userspacebe átmappelésekor több ellenőrzést végez, mintha a kernelen belül férnénk hozzá, de ez az ellenőrzés nem hiábavaló, ugyanis megakadályozza, hogy az esetleg a hibásan működő fs kód kicímezzen a tartományból és ezzel gyakorlatilag a kernelben akármit felülírjon. (Az ilyen kicímzések piszok nehezen megfogható hibák, legalábbis én régebben igen sokat szoptam mikor ilyet kellett debuggolnom. A fő baj vele, hogy egészen máshol bukik ki a hibajelenség, mint ahol az oka van.) Egy jó megbízható natív filerendszer implementációnak saját magának is célszerű ellenőrzéseket végeznie. Tehát a második probléma szerintem megoldható memóriamásolás nélkül is, illetve ha a hw driver miatt mégsem, akkor az egyformán sújtja a nativ filerendszert és a fuse-t is.
Az első számú probléma, vagyis a fuse api hívásokban átadott pointerek által hivatkozott tömbök kezelése a fuse core implementáció felelőssége. Mivel elég triviális leképezés van a vfs hívások és a fuse között, ezért szerinten ez is megúszható másolás nélkül egy mmap hívással. Kérdés, hogy így van-e megoldva. Ha nincs elvi akadálya, de mégsem így van, azon csodálkoznék, de mindenesetre a későbbiekben akkor ez fejleszthető.
A harmadik vagyis a belső adatmozgatás a mappelt eszköz és a read/write tömbjei között, na ez egy cseles kérdés. int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *); Ha kétszeres indirekció lenne a második paraméternél, akkor triviális lenne a válasz, hogy lehet másolás nélkül, csupán pointerbűvészkedéssel tömböt átadni. Enélkül probléma az, hogy a read egy kívülről adott címen várja az adatot, amit belülről nem tudok befolyásolni. Nade nem ugyanez a helyzet a natív vfs esetén is? Tehát 1db másolást sehogyan sem lehet megúszni? Arról meg aztán nem is beszélve, hogy sok esetben a filerendszer nem is 1:1 tárolja az fájlok tartalmát. Titkosítás, tömörítés egyértelmű, bár nem túl elterjedt, de pl az inode mezőkbe elrakott rezidens fájlok sem túl egyszerűek (asszem az ext3-ban még vannak). Ráadásul memória mappeléssel csak egész számú page-et lehet átadni, viszont úgy tudom, hogy a read/write függvényeket tetszőleges számú charból álló tömbbel lehet hívni. Ez alól a kernel módban futó fs sem kivétel.
Lehet, hogy van valami amit nem teljesen jól tudok, vagy átsiklottam felette, de egyelőre úgy látom, hogy a fuse nem jelent semmi különös megszorítást a vfs metódusaihoz képest.
---
Sok gyerekkel ellentétben én sose akartam tűzoltó lenni. Lettem helyette informatikus. Nem találjátok ki, hogy mit csinálok nap mint nap...