A nyílt forráskódú szoftvereken dolgozó fejlesztő, Mateusz Guzik vezeti azt a munkát, amely a Linux kernel do_open() VFS függvényének optimalizálására irányul. Ezt a függvényt a fájlmegnyitás során használják, amikor az elérési útból kikeresik a fájlt. Jelenleg a folyamat során duplikált könyvtárbejegyzés, úgynevezett „dentry” jön létre, amely a path komponensből a lemezen lévő inode-ra fordít. Guzik ezt a felesleges dentry-t iktatja ki. Guzik a javítócsomagban magyarázta el a részleteket, amely az elmúlt két évben öt változáson ment át:
"A fájl megnyitásakor a __legitimize_path() fog egy hivatkozást a végső dentry-re, majd a do_dentry_open() fog még egyet, végül a terminate_walk() eldobja az első hivatkozást.
Ez 2 fölösleges módosítás – a do_dentry_open() felhasználhatja a már meglévő hivatkozást is."
Az ilyen felesleges munka elhagyása meglepően nagy előnyt hoz: egy 20 magos virtuális gépen, a will-it-scale benchmarkkal mérve, ahol ugyanazt a fájlt nyitják meg csak olvasásra, a másodpercenkénti műveletek száma 39%-kal nőtt. Meglepő, hogy egy ilyen „könnyen lecsíphető” optimalizáció ilyen sokáig bent maradt a Linux kernel-ben. Jó hír viszont, hogy a fejlesztés várhatóan 2026 vége előtt bekerül a stabil kernel-be. A nagyjából három tucat sornyi kódból álló javítócsomagot már beütemezték a VFS.Git vfs-7.4.lookup Git ágba. Mivel a javítócsomag mostanra egy hivatalos VFS alrendszerbeli Git ágban van, és „7.4-es” anyagként jelölték meg, várhatóan benyújtják az érkező Linux 7.4 merge ablakában.
A VFS, a dentry, az inode és a fájl megnyitása
A Linux kernel fájlkezelésének egyik legfontosabb eleme a VFS (Virtual File System, virtuális fájlrendszer), amely egységes felületet biztosít a különböző fájlrendszerek, például az ext4, az XFS vagy a Btrfs és az alkalmazások között. Amikor egy program egy fájl megnyitását, lekérdezését vagy módosítását kéri, a VFS feladata, hogy a megadott útvonalból megtalálja a hozzá tartozó fájlrendszer-objektumot.
Ebben fontos szerepet játszik a dentry cache, röviden dcache. A dentry, vagyis directory entry egy kernelbeli objektum, amely elsősorban egy fájlnév vagy könyvtárnév és a hozzá tartozó fájlrendszer-objektum közötti kapcsolatot képviseli. Ha például egy program a /home/felhasznalo/dokumentum.txt fájlt akarja megnyitni, a VFS az útvonal egyes elemein végighaladva keresi meg a megfelelő dentryket. A már korábban használt útvonalakhoz tartozó dentryk a memóriában található dcache-ben maradhatnak, így a kernelnek nem kell minden alkalommal újra végrehajtania a teljes keresést. Ez jelentősen felgyorsítja a fájlnevek feloldását.
A dentry cache azonban csak gyorsítótár, nem maga a fájlrendszer. A dentryk alapvetően a teljesítmény javítása érdekében léteznek a memóriában, és a kernel szükség esetén újra létre tudja őket. Ha egy keresett dentry nincs a cache-ben, a VFS a konkrét fájlrendszer segítségével megkeresi a hozzá tartozó objektumot.
Itt kerül képbe az inode. Az inode a fájlrendszer egy objektumát – például egy normál fájlt, könyvtárat vagy más fájlrendszer-objektumot – reprezentálja, és annak fontos metaadatait tartalmazza. Ide tartozhat például a fájl mérete, típusa, jogosultsága, tulajdonosa és időbélyegei. Fontos különbség, hogy az inode nem a fájl nevét tárolja. A fájlnév feloldásában a dentry vesz részt, amely az inode-ra hivatkozik. Emiatt akár több különböző dentry is ugyanarra az inode-ra mutathat, például hard linkek esetén.
Miután a VFS megtalálta a megfelelő dentryt és inode-ot, a fájl még nincs feltétlenül megnyitva. Az open() rendszerhívás során a kernel létrehoz egy file objektumot, amely az adott megnyitás kernelbeli reprezentációja. Ez kapcsolja össze a megnyitott fájlhoz tartozó állapotot a dentryvel és az inode által meghatározott fájlrendszer-műveletekkel. A felhasználói program ebből végül egy file descriptort, vagyis fájlleírót kap, például a 3 értéket. Amikor a program később read(), write() vagy close() műveletet hajt végre, ezt a fájlleírót használja a kernel a megfelelő file objektum megtalálásához.
A folyamat tehát leegyszerűsítve úgy képzelhető el, hogy a program egy útvonalat ad meg, a VFS ebből megkeresi a megfelelő dentryt, a dentry segítségével eljut az inode-hoz, majd a fájl megnyitásakor létrejön a hozzá tartozó file objektum, amelyhez a program egy file descriptoron keresztül fér hozzá. A dentry tehát elsősorban a név feloldásában, az inode a fájlrendszer-objektum leírásában, a file objektum pedig az adott megnyitás kezelésében fontos.
Ennek a folyamatnak van egy kevésbé látványos, de teljesítmény szempontjából fontos része is: a hivatkozásszámlálás (reference counting). A kernelnek nyilván kell tartania, hogy egy adott objektumot – például egy dentryt – hány kernelbeli felhasználó tart még életben. Amíg van rá érvényes hivatkozás, az objektumot nem lehet egyszerűen felszabadítani. Ez egy általános és alapvető memória- és objektumélettartam-kezelési mechanizmus a Linux kernelben.
A fájl megnyitásának folyamatában a dentry hivatkozásszámlálása is változhat. A megadott kódrészlet szerint a fájl megnyitásakor a __legitimize_path() egy hivatkozást szerez a végső dentryre, majd a do_dentry_open() további hivatkozást szerez ugyanarra a dentryre. Ezután a terminate_walk() eldobja az első hivatkozást.
Ez önmagában működőképes, de azt jelenti, hogy ugyanannak az objektumnak a hivatkozásszámlálóját feleslegesen kétszer módosítják: egyszer növelik, majd később csökkentik, miközben a második hivatkozás továbbra is szükséges. A megfogalmazás szerint ezért két fölösleges hivatkozásszámláló-módosítás történik. A javasolt optimalizáció lényege, hogy a do_dentry_open() egyszerűen felhasználhatná a __legitimize_path() által már megszerzett hivatkozást, ahelyett, hogy újabbat venne.
Ez első látásra apró változtatásnak tűnik, hiszen nem a fájl tartalma, nem a fájlrendszer struktúrája és nem is a felhasználó által érzékelhető működés változik meg. A kernelben azonban az ilyen műveletek nagyon gyakran, nagyon sokszor hajtódnak végre. Egy fájl megnyitásakor néhány extra referencia-számláló-művelet önmagában gyakorlatilag mérhetetlen lehet, nagyon sok fájlművelet során összeadódva viszont felesleges CPU-munkát és memória-koherencia-forgalmat jelenthet.
A hivatkozásszámlálás különösen érdekes többmagos rendszereken, mert az ilyen számlálók módosítása nem egyszerűen egy változó átírását jelenti. A kernelnek biztosítania kell, hogy párhuzamosan futó processzorok és kernel-szálak mellett is helyes maradjon az objektum élettartama. Emiatt a referencia megszerzése és elengedése megfelelő szinkronizációt és memóriaműveleteket igényelhet. Ha tehát egy hivatkozás már rendelkezésre áll, annak felesleges eldobása és egy újabb megszerzése kerülendő.
A változtatás jelentősége ezért nem abban áll, hogy látványosan megváltozik a fájlok megnyitásának működése, hanem abban, hogy a kernel egy gyakran végrehajtott útvonalán csökkenti a szükségtelen munkát. Ez tipikusan olyan kerneloptimalizáció, amely önmagában apróságnak tűnik, de a fájlmegnyitások nagy száma miatt összességében javíthatja a hatékonyságot.

