fuse(4)

NUME
fuse - dispozitiv cu sistem de fișiere în spațiul utilizatorului („Filesystem in Userspace”: FUSE)

SINOPSIS
#include <linux/fuse.h>

DESCRIERE
Acest dispozitiv este interfața principală dintre controlorul sistemului de fișiere FUSE și un proces din spațiul utilizatorului care dorește să furnizeze sistemul de fișiere (denumit în restul acestei pagini de manual demon de sistem de fișiere). Această pagină de manual este destinată celor interesați să înțeleagă interfața nucleului în sine. Cei care implementează un sistem de fișiere FUSE pot dori să utilizeze o bibliotecă din spațiul utilizatorului, cum ar fi libfuse, care abstractizează interfața de nivel scăzut.

În esența sa, FUSE este un protocol client-server simplu, în care nucleul Linux este clientul, iar demonul este serverul. După obținerea unui descriptor de fișier pentru acest dispozitiv, demonul poate read(2) cereri de la acel descriptor de fișier și se așteaptă să write(2) înapoi răspunsurile sale. Este important de reținut că un descriptor de fișier este asociat cu un sistem de fișiere FUSE unic. În special, deschiderea unei a doua copii a acestui dispozitiv, nu va permite accesul la resursele create prin intermediul primului descriptor de fișier (și viceversa).

  Protocolul de bază
Fiecare mesaj citit de daemon începe cu un antet descris de următoarea structură:

    struct fuse_in_header {
        uint32_t len;       /* Dimensiunea totală a datelor,
                               inclusiv acest antet */
        uint32_t opcode;    /* Tipul de operație (a se vedea mai jos) */
        uint64_t unique;    /* Un identificator unic pentru această cerere */
        uint64_t nodeid;    /* ID-ul obiectului sistemului de fișiere
                               asupra căruia se operează */
        uint32_t uid;       /* UID-ul procesului solicitant */
        uint32_t gid;       /* GID-ul procesului solicitant */
        uint32_t pid;       /* PID-ul procesului solicitant */
        uint32_t padding;
    };

Antetul este urmat de o porțiune de date de dimensiune variabilă (care poate fi goală) specifică operației solicitate (operația solicitată este indicată prin opcode).

Demonul ar trebui apoi să proceseze cererea și, dacă este cazul, să trimită un răspuns (aproape toate operațiile necesită un răspuns; dacă nu, acest lucru este documentat mai jos), prin efectuarea unui write(2) către descriptorul de fișier. Toate răspunsurile trebuie să înceapă cu următorul antet:

    struct fuse_out_header {
        uint32_t len;       /* Dimensiunea totală a datelor scrise
                               în descriptorul de fișier */
        int32_t  error;     /* Orice eroare apărută (0 dacă nu există) */
        uint64_t unique;    /* Valoarea din cererea
                               corespondentă */
    };

Acest antet este urmat, de asemenea, de date de dimensiune variabilă (potențial goale) în funcție de cererea executată. Cu toate acestea, dacă răspunsul este un răspuns de eroare (și anume, error este configurată), atunci nu trebuie trimise alte date utile, independent de cerere.

  Mesaje schimbate
Această secțiune ar trebui să conțină documentația pentru fiecare dintre mesajele din protocol. Această pagină de manual este în prezent incompletă, astfel încât nu toate mesajele sunt documentate. Pentru fiecare mesaj, este prezentată mai întâi structura trimisă de nucleu, urmată de o descriere a semanticii mesajului.

FUSE_INIT

        struct fuse_init_in {
            uint32_t major;
            uint32_t minor;
            uint32_t max_readahead; /* Începând cu protocolul v7.6 */
            uint32_t flags;         /* Începând cu protocolul v7.6 */
        };

    Aceasta este prima solicitare trimisă de nucleu către demon. Aceasta este utilizată pentru a negocia versiunea protocolului și alți parametri ai sistemului de fișiere. Rețineți că versiunea protocolului poate afecta aspectul oricărei structuri din protocol (inclusiv această structură). Prin urmare, demonul trebuie să memoreze versiunea și fanioanele negociate pentru fiecare sesiune. La momentul redactării acestei pagini de manual, cea mai mare versiune de protocol a nucleului acceptată este 7.26.

    Utilizatorii trebuie să fie conștienți de faptul că descrierile din această pagină de manual pot fi incomplete sau incorecte pentru versiunile de protocol mai vechi sau mai recente.

    Răspunsul pentru această cerere are următorul format:

        struct fuse_init_out {
            uint32_t major;
            uint32_t minor;
            uint32_t max_readahead;   /* Începând cu v7.6 */
            uint32_t flags;           /* Începând cu v7.6; unii biți de
                                         fanioane au fost introduși târziu */
            uint16_t max_background;  /* Începând cu v7.13 */
            uint16_t congestion_threshold;  /* Începând cu v7.13 */
            uint32_t max_write;       /* Începând cu v7.5 */
            uint32_t time_gran;       /* Începând cu v7.6 */
            uint32_t unused[9];
        };

    În cazul în care versiunea majoră admisă de nucleu este mai mare decât cea admisă de demon, răspunsul va consta doar din uint32_t major (după antetul obișnuit), indicând cea mai mare versiune majoră admisă de demon. Nucleul va emite apoi o nouă cerere FUSE_INIT conformă cu versiunea mai veche. În cazul invers, demonul ar trebui să revină în liniște la versiunea majoră a nucleului.

    Versiunea minoră negociată este considerată a fi cea mai mică dintre versiunile minore furnizate de demon și de nucleu și ambele părți trebuie să utilizeze protocolul corespunzător versiunii minore respective.

FUSE_GETATTR

        struct fuse_getattr_in {
            uint32_t getattr_flags;
            uint32_t dummy;
            uint64_t fh;      /* Definit doar dacă
                                 (getattr_flags & FUSE_GETATTR_FH)
        };

    Operația solicitată constă în calcularea atributelor care urmează să fie returnate de stat(2) și alte operații similare pentru obiectul sistemului de fișiere dat. Obiectul pentru care ar trebui calculate atributele este indicat fie prin header->nodeid, fie, în cazul în care fanionul FUSE_GETATTR_FH este activat, prin gestionarul de fișier fh. Acest din urmă caz de operare este analog cu fstat(2).

    Din motive de performanță, aceste atribute pot fi stocate în memoria cache a nucleului pentru o anumită perioadă de timp. Atât timp cât timpul de așteptare în cache nu a fost depășit, atributele vor fi servite din cache și nu vor cauza cereri suplimentare FUSE_GETATTR.

    Atributele calculate și timpul de așteptare în cache solicitat ar trebui apoi returnate în următoarea structură:

        struct fuse_attr_out {
            /* Durata cache-ului de atribute (secunde + nanosecunde) */
            uint64_t attr_valid;
            uint32_t attr_valid_nsec;
            uint32_t dummy;
            struct fuse_attr {
                uint64_t ino;
                uint64_t size;
                uint64_t blocks;
                uint64_t atime;
                uint64_t mtime;
                uint64_t ctime;
                uint32_t atimensec;
                uint32_t mtimensec;
                uint32_t ctimensec;
                uint32_t mode;
                uint32_t nlink;
                uint32_t uid;
                uint32_t gid;
                uint32_t rdev;
                uint32_t blksize;
                uint32_t padding;
            } attr;
        };

FUSE_ACCESS

        struct fuse_access_in {
            uint32_t mask;
            uint32_t padding;
        };

    Dacă opțiunile de montare default_permissions nu sunt utilizate, această cerere poate fi utilizată pentru verificarea permisiunilor. Nu se așteaptă date de răspuns, dar erorile pot fi indicate ca de obicei prin definirea câmpului error din antetul răspunsului (în special, erorile de acces refuzat pot fi indicate prin returnarea -EACCES).

FUSE_OPEN
FUSE_OPENDIR
        struct fuse_open_in {
            uint32_t flags;     /* Fanioanele care au fost transmise
                                   către open(2) */
            uint32_t unused;
        };

    Operația solicitată este de a deschide nodul indicat de header->nodeid. Semantica exactă a ceea ce înseamnă acest lucru va depinde de sistemul de fișiere implementat Cu toate acestea, cel puțin sistemul de fișiere ar trebui să valideze că fanioanele solicitate sunt valabile pentru resursa indicată și apoi să trimită un răspuns cu următorul format:

        struct fuse_open_out {
            uint64_t fh;
            uint32_t open_flags;
            uint32_t padding;
        };

    Câmpul fh este un identificator opac pe care nucleul îl va utiliza pentru a se referi la această resursă. Câmpul open_flags este o mască de biți a oricărui număr de fanioane care indică proprietățile acestui gestionar de fișier pentru nucleu:

    FOPEN_DIRECT_IO
        Ocolește cache-ul paginii pentru acest fișier deschis.

    FOPEN_KEEP_CACHE
        Nu se invalidează memoria cache de date la deschidere.

    FOPEN_NONSEEKABLE
        Fișierul nu poate fi explorat.

FUSE_READ
FUSE_READDIR

        struct fuse_read_in {
            uint64_t fh;
            uint64_t offset;
            uint32_t size;
            uint32_t read_flags;
            uint64_t lock_owner;
            uint32_t flags;
            uint32_t padding;
        };

    Acțiunea solicitată este de a citi până la size octeți din fișier sau director, începând de la offset. Octeții ar trebui să fie returnați direct după antetul de răspuns obișnuit.

FUSE_INTERRUPT
        struct fuse_interrupt_in {
            uint64_t unique;
        };

    Acțiunea solicitată este de a anula operația în așteptare indicată de unique. Această cerere nu necesită răspuns. Cu toate acestea, primirea acestui mesaj nu anulează de la sine operația indicată. Nucleul va aștepta în continuare un răspuns la operația respectivă (de exemplu, o eroare EINTR sau o citire scurtă). Pentru o operație dată va fi emisă cel mult o cerere FUSE_INTERRUPT. După emiterea operației respective, nucleul va aștepta neîntrerupt finalizarea cererii indicate.

FUSE_LOOKUP
    Imediat după antet urmează un nume de fișier care trebuie căutat în directorul indicat de header->nodeid. Răspunsul așteptat este de forma:

        struct fuse_entry_out {
            uint64_t nodeid;            /* ID-ul nodului-i */
            uint64_t generation;        /* Generarea nodului-i */
            uint64_t entry_valid;
            uint64_t attr_valid;
            uint32_t entry_valid_nsec;
            uint32_t attr_valid_nsec;
            struct fuse_attr attr;
        };

    Combinația de nodeid și generation trebuie să fie unică pe durata de viață a sistemului de fișiere.

    Interpretarea timpilor de așteptare și a attr este aceeași ca pentru FUSE_GETATTR.

FUSE_FLUSH
        struct fuse_flush_in {
            uint64_t fh;
            uint32_t unused;
            uint32_t padding;
            uint64_t lock_owner;
        };

    Acțiunea solicitată este de a șterge orice modificări în așteptare pentru gestionarul fișierului indicat. Nu sunt așteptate date de răspuns. Cu toate acestea, un mesaj de răspuns gol trebuie să fie emis după finalizarea operației de golire.

FUSE_RELEASE
FUSE_RELEASEDIR
        struct fuse_release_in {
            uint64_t fh;
            uint32_t flags;
            uint32_t release_flags;
            uint64_t lock_owner;
        };

    Acestea sunt inversul lui FUSE_OPEN și respectiv FUSE_OPENDIR. Daemonul poate elibera acum orice resurse asociate cu gestionarul fișierului fh, deoarece nucleul nu se va mai referi la acesta. Nu există date de răspuns asociate cu această cerere, dar un răspuns trebuie să fie emis după ce cererea a fost complet procesată.

FUSE_STATFS
    Această operație implementează statfs(2) pentru acest sistem de fișiere. Nu există date de intrare asociate cu această cerere. Datele de răspuns așteptate au următoarea structură:

        struct fuse_kstatfs {
            uint64_t blocks;
            uint64_t bfree;
            uint64_t bavail;
            uint64_t files;
            uint64_t ffree;
            uint32_t bsize;
            uint32_t namelen;
            uint32_t frsize;
            uint32_t padding;
            uint32_t spare[6];
        };

        struct fuse_statfs_out {
            struct fuse_kstatfs st;
        };

    Pentru interpretarea acestor câmpuri, a se vedea statfs(2).

ERORI-IEȘIRE

E2BIG
    Returnată din operațiile read(2) atunci când solicitarea nucleului este prea mare pentru memoria tampon furnizată și solicitarea a fost FUSE_SETXATTR.

EINVAL
    Returnată de la write(2) dacă validarea răspunsului a eșuat. Nu toate erorile din răspunsuri vor fi detectate de această validare. Cu toate acestea, greșelile de bază, cum ar fi răspunsurile scurte sau o valoare unique incorectă, sunt detectate.

EIO Returnată de operațiile read(2) atunci când solicitarea nucleului este prea mare pentru memoria tampon furnizată.

    Notă: Există diverse moduri în care utilizarea incorectă a acestor interfețe poate cauza eșecul operațiilor asupra fișierelor și directoarelor din sistemul de fișiere furnizat cu EIO. Printre posibilele utilizări incorecte se numără:

    •   schimbarea mode & S_IFMT pentru un nod-i care a fost raportat anterior către nucleu; sau

    •   furnizarea de răspunsuri către nucleu care sunt mai scurte decât cele așteptate de acesta.

ENODEV
    Returnată de read(2) și write(2) dacă sistemul de fișiere FUSE a fost demontat.

EPERM
    Returnată în urma operațiilor pe un descriptor de fișier /dev/fuse care nu a fost montat.

STANDARDE
Linux.

NOTE
Următoarele mesaje nu sunt încă documentate în această pagină de manual:

    FUSE_BATCH_FORGET
    FUSE_BMAP
    FUSE_CREATE
    FUSE_DESTROY
    FUSE_FALLOCATE
    FUSE_FORGET
    FUSE_FSYNC
    FUSE_FSYNCDIR
    FUSE_GETLK
    FUSE_GETXATTR
    FUSE_IOCTL
    FUSE_LINK
    FUSE_LISTXATTR
    FUSE_LSEEK
    FUSE_MKDIR
    FUSE_MKNOD
    FUSE_NOTIFY_REPLY
    FUSE_POLL
    FUSE_READDIRPLUS
    FUSE_READLINK
    FUSE_REMOVEXATTR
    FUSE_RENAME
    FUSE_RENAME2
    FUSE_RMDIR
    FUSE_SETATTR
    FUSE_SETLK
    FUSE_SETLKW
    FUSE_SYMLINK
    FUSE_UNLINK
    FUSE_WRITE

CONSULTAȚI ȘI
fusermount(1), mount.fuse(8)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.