fuse(4)

الاسم
fuse - جهاز نظام ملفات في مساحة المستخدم (FUSE)

موجز
#include <linux/fuse.h>

الوصف
يعد هذا الجهاز الواجهة الرئيسة بين محرك نظام ملفات FUSE وعملية في مساحة المستخدم ترغب في توفير نظام الملفات (يُشار إليها في بقية صفحة الدليل هذه باسم عفريت نظام الملفات). تهدف صفحة الدليل هذه للمهتمين بفهم واجهة النواة ذاتها. أما من ينفذون نظام ملفات FUSE فقد يرغبون في استخدام مكتبة في مساحة المستخدم مثل libfuse التي تجرّد الواجهة منخفضة المستوى.

يُعد FUSE في جوهره بروتوكول عميل-خادم بسيط، تكون فيه نواة لينكس هي العميل والعفريت هو الخادم. بعد الحصول على واصف ملف لهذا الجهاز، يمكن للعفريت قراءة read(2) الطلبات من واصف الملف هذا ويُتوقع منه كتابة write(2) ردوده. من المهم ملاحظة أن واصف الملف يرتبط بنظام ملفات FUSE فريد. وبوجه خاص، فإن فتح نسخة ثانية من هذا الجهاز لن يسمح بالوصول إلى الموارد المنشأة عبر واصف الملف الأول (والعكس صحيح).

  البروتوكول الأساسي
تبدأ كل رسالة يقرؤها العفريت بترويسة يصفها الهيكل التالي:

    struct fuse_in_header {
        uint32_t len;       /* الحجم الإجمالي للبيانات،
                               بما في ذلك هذه الترويسة */
        uint32_t opcode;    /* نوع العملية (انظر أدناه) */
        uint64_t unique;    /* معرف فريد لهذا الطلب */
        uint64_t nodeid;    /* معرف كائن نظام الملفات
                               الجاري العمل عليه */
        uint32_t uid;       /* UID للعملية الطالبة */
        uint32_t gid;       /* GID للعملية الطالبة */
        uint32_t pid;       /* PID للعملية الطالبة */
        uint32_t padding;
    };

تتبع الترويسة جزء بيانات متغير الحجم (قد يكون فارغًا) خاص بالعملية المطلوبة (يُشار إلى العملية المطلوبة بواسطة opcode).

يجب على العفريت بعد ذلك معالجة الطلب و —إذا أمكن— إرسال رد (تتطلب جميع العمليات تقريبًا ردًا؛ وإذا لم تكن كذلك، فسيُوثق هذا أدناه)، وذلك عن طريق إجراء write(2) إلى واصف الملف. يجب أن تبدأ جميع الردود بالترويسة التالية:

    struct fuse_out_header {
        uint32_t len;       /* الحجم الإجمالي للبيانات المكتوبة في
                               واصف الملف */
        int32_t  error;     /* أي خطأ حدث (0 في حال عدم وجود خطأ) */
        uint64_t unique;    /* القيمة من
                               الطلب المقابل */
    };

تتبع هذه الترويسة أيضًا بيانات متغيرة الحجم (قد تكون فارغة) اعتمادًا على الطلب المنفذ. ومع ذلك، إذا كان الرد عبارة عن رد خطأ (أي ضُبط error)، فلا ينبغي إرسال أي بيانات حمولة أخرى، بغض النظر عن الطلب.

  الرسائل المتبادلة
يجب أن يحتوي هذا القسم على توثيق لكل رسالة من رسائل البروتوكول. صفحة الدليل هذه غير مكتملة حاليًا، لذا لم تُوثق جميع الرسائل. لكل رسالة، يُعطى أولاً الهيكل المرسل من قبل النواة، يليه وصف لدلالات الرسالة.

FUSE_INIT

        struct fuse_init_in {
            uint32_t major;
            uint32_t minor;
            uint32_t max_readahead; /* منذ إصدار البروتوكول v7.6 */
            uint32_t flags;         /* منذ إصدار البروتوكول v7.6 */
        };

    هذا هو أول طلب ترسله النواة إلى العفريت. يُستخدم للتفاوض على إصدار البروتوكول ومعاملات نظام الملفات الأخرى. لاحظ أن إصدار البروتوكول قد يؤثر على تخطيط أي هيكل في البروتوكول (بما في ذلك هذا الهيكل). يجب على العفريت بالتالي تذكر الإصدار والأعلام المتفاوض عليها لكل جلسة. حتى وقت كتابة صفحة الدليل هذه، فإن أعلى إصدار بروتوكول نواة مدعوم هو 7.26.

    يجب أن يدرك المستخدمون أن الأوصاف الواردة في صفحة الدليل هذه قد تكون غير مكتملة أو غير صحيحة لإصدارات البروتوكول الأقدم أو الأحدث.

    الرد على هذا الطلب له التنسيق التالي:

        struct fuse_init_out {
            uint32_t major;
            uint32_t minor;
            uint32_t max_readahead;   /* منذ v7.6 */
            uint32_t flags;           /* منذ v7.6؛ أُدخلت بعض بتات الأعلام
                                         لاحقًا */
            uint16_t max_background;  /* منذ v7.13 */
            uint16_t congestion_threshold;  /* منذ v7.13 */
            uint32_t max_write;       /* منذ v7.5 */
            uint32_t time_gran;       /* منذ v7.6 */
            uint32_t unused[9];
        };

    إذا كان الإصدار الرئيس الذي تدعمه النواة أكبر من ذلك الذي يدعمه العفريت، يجب أن يتكون الرد من uint32_t major فقط (بعد الترويسة المعتادة)، مما يشير إلى أكبر إصدار رئيس يدعمه العفريت. ستصدر النواة بعد ذلك طلب FUSE_INIT جديد يتوافق مع الإصدار الأقدم. في الحالة المعاكسة، يجب على العفريت التراجع بهدوء إلى الإصدار الرئيس للنواة.

    يُعتبر الإصدار الفرعي المتفاوض عليه هو الحد الأدنى من الإصدارات الفرعية التي يقدمها العفريت والنواة، ويجب على الطرفين استخدام البروتوكول المقابل للإصدار الفرعي المذكور.

FUSE_GETATTR

        struct fuse_getattr_in {
            uint32_t getattr_flags;
            uint32_t dummy;
            uint64_t fh;      /* يُضبط فقط إذا كان
                                 (getattr_flags & FUSE_GETATTR_FH)
        };

    العملية المطلوبة هي حساب السمات التي ستُرجع بواسطة stat(2) والعمليات المماثلة لكائن نظام الملفات المعطى. يُشار إلى الكائن الذي يجب حساب سماته إما بواسطة header->nodeid أو، إذا ضُبط علم FUSE_GETATTR_FH، بواسطة مقبض الملف fh. حالة العملية الأخيرة مماثلة لـ fstat(2).

    لأسباب تتعلق بالأداء، قد تُخزن هذه السمات في خبيئة النواة لفترة زمنية محددة. طالما لم يتم تجاوز مهلة الخبيئة، ستُقدم السمات من الخبيئة ولن تتسبب في طلبات FUSE_GETATTR إضافية.

    يجب بعد ذلك إرجاع السمات المحسوبة ومهلة الخبيئة المطلوبة في الهيكل التالي:

        struct fuse_attr_out {
            /* مدة خبيئة السمات (ثوانٍ + نانو ثانية) */
            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;
        };

    إذا لم يُستخدم خيار الوصل default_permissions، فقد يُستخدم هذا الطلب للتحقق من الأذونات. لا يُتوقع وجود بيانات رد، ولكن قد يُشار إلى الأخطاء كالمعتاد عن طريق ضبط حقل error في ترويسة الرد (وبوجه خاص، قد يُشار إلى أخطاء رفض الوصول عن طريق إرجاع -EACCES).

FUSE_OPEN
FUSE_OPENDIR
        struct fuse_open_in {
            uint32_t flags;     /* الأعلام التي مُررت
                                   إلى open(2) */
            uint32_t unused;
        };

    العملية المطلوبة هي فتح العقدة المشار إليها بواسطة header->nodeid. ستعتمد الدلالات الدقيقة لمعنى هذا على نظام الملفات الذي يُنفذ. ومع ذلك، يجب على نظام الملفات على الأقل التحقق من صحة الأعلام المطلوبة للمورد المشار إليه ثم إرسال رد بالتنسيق التالي:

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

    حقل fh هو معرف مبهم ستستخدمه النواة للإشارة إلى هذا المورد. حقل open_flags هو قناع بتات لأي عدد من الأعلام التي تشير إلى خصائص مقبض الملف هذا للنواة:

    FOPEN_DIRECT_IO
        تجاوز خبيئة الصفحة لهذا الملف المفتوح.

    FOPEN_KEEP_CACHE
        لا تبطل خبيئة البيانات عند الفتح.

    FOPEN_NONSEEKABLE
        الملف غير قابل للبحث (seekable).

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;
        };

    الإجراء المطلوب هو قراءة ما يصل إلى size من البايتات من الملف أو الدليل، بدءًا من offset. يجب إرجاع البايتات مباشرة بعد ترويسة الرد المعتادة.

FUSE_INTERRUPT
        struct fuse_interrupt_in {
            uint64_t unique;
        };

    الإجراء المطلوب هو إلغاء العملية المعلقة المشار إليها بواسطة unique. لا يتطلب هذا الطلب أي استجابة. ومع ذلك، فإن استلام هذه الرسالة لا يؤدي بحد ذاته إلى إلغاء العملية المشار إليها. ستظل النواة تتوقع ردًا على العملية المذكورة (على سبيل المثال، خطأ EINTR أو قراءة قصيرة). سيُصدر طلب FUSE_INTERRUPT واحد على الأكثر لعملية معينة. بعد إصدار العملية المذكورة، ستنتظر النواة دون انقطاع حتى اكتمال الطلب المشار إليه.

FUSE_LOOKUP
    بعد الترويسة مباشرة يوجد اسم ملف يُبحث عنه في الدليل المشار إليه بواسطة header->nodeid. الرد المتوقع يكون على النموذج:

        struct fuse_entry_out {
            uint64_t nodeid;            /* معرف Inode */
            uint64_t generation;        /* جيل Inode */
            uint64_t entry_valid;
            uint64_t attr_valid;
            uint32_t entry_valid_nsec;
            uint32_t attr_valid_nsec;
            struct fuse_attr attr;
        };

    يجب أن يكون الجمع بين nodeid و generation فريدًا طوال عمر نظام الملفات.

    تفسير المهل و attr هو نفسه بالنسبة لـ FUSE_GETATTR.

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

    الإجراء المطلوب هو دفع (flush) أي تغييرات معلقة إلى مقبض الملف المشار إليه. لا يُتوقع وجود بيانات رد. ومع ذلك، لا تزال هناك حاجة لإصدار رسالة رد فارغة بمجرد اكتمال عملية الدفع.

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

    هذه هي عكس FUSE_OPEN و FUSE_OPENDIR على التوالي. يمكن للعفريت الآن تحرير أي موارد مرتبطة بمقبض الملف fh لأن النواة لن تشير إليه بعد الآن. لا توجد بيانات رد مرتبطة بهذا الطلب، ولكن لا يزال يتعين إصدار رد بمجرد معالجة الطلب بالكامل.

FUSE_STATFS
    تنفذ هذه العملية statfs(2) لنظام الملفات هذا. لا توجد بيانات إدخال مرتبطة بهذا الطلب. بيانات الرد المتوقعة لها الهيكل التالي:

        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;
        };

    لتفسير هذه الحقول، انظر statfs(2).

الأخطاء

E2BIG
    يُرجع من عمليات read(2) عندما يكون طلب النواة كبيرًا جدًا بالنسبة للمخزن المؤقت المقدم وكان الطلب FUSE_SETXATTR.

EINVAL
    يُرجع من write(2) إذا فشل التحقق من صحة الرد. لن تكتشف عملية التحقق هذه جميع الأخطاء في الردود. ومع ذلك، تُكتشف الأخطاء الأساسية، مثل الردود القصيرة أو قيمة unique غير الصحيحة.

EIO يُرجع من عمليات read(2) عندما يكون طلب النواة كبيرًا جدًا بالنسبة للمخزن المؤقت المقدم.

    ملاحظة: هناك طرق مختلفة يمكن أن يؤدي بها الاستخدام غير الصحيح لهذه الواجهات إلى فشل العمليات على ملفات ودلائل نظام الملفات المقدم مع EIO. ومن بين الاستخدامات غير الصحيحة الممكنة:

    •   تغيير mode & S_IFMT لـ inode أُبلغت به النواة سابقًا؛ أو

    •   إعطاء ردود للنواة أقصر مما توقعته النواة.

ENODEV
    يُرجع من read(2) و write(2) إذا فُصل نظام ملفات FUSE.

EPERM
    يُرجع من العمليات على واصف ملف /dev/fuse لم يُوصل.

المعايير
لينكس.

ملاحظات
الرسائل التالية لم تُوثق بعد في صفحة الدليل هذه:

    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

انظر أيضًا
fusermount(1), mount.fuse(8)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.