• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            風雨兼程

            ring my bells
            posts - 49, comments - 14, trackbacks - 0, articles - 0

            Linux虛擬文件系統(tǒng)概述

            Posted on 2008-04-16 21:18 silentneil 閱讀(441) 評論(0)  編輯 收藏 引用
            一、簡介:
            虛擬文件系統(tǒng)(也叫虛擬文件系統(tǒng)交換層)是在內核實現(xiàn)的一個軟件層,它既為用戶空間程序提供文件系統(tǒng)接口的調用,也是保證系統(tǒng)內核各種文件系統(tǒng)實現(xiàn)能夠共存的抽象層。
            VFS系統(tǒng)調用如open(2), stat(2), read(2), write(2), chmod(2)等在進程上下文中被調用。文件系統(tǒng)鎖在文檔Documentation/filesystems/Locking中描述。
            1、目錄結構緩存(dcache)
            VFS實現(xiàn)了open(2), stat(2), chmod(2)以及其它類似的系統(tǒng)調用。VFS利用傳遞給這些調用的文件路徑參數(shù)在目錄入口緩存(dcache 或者目錄機構緩存)中進行查找。通過一種快速的轉換機制將文件路徑轉化為特定的目錄入口。目錄結構緩存只存在在RAM中而從不寫入磁盤,他們只是為了提高性能而創(chuàng)建的。
            目錄結構緩存是整個文件空間的視圖,但是絕大多數(shù)計算機并沒有足夠的空間將所有的目錄結構同時放在RAM中,因此某些緩存將會丟棄。為了解決目錄結構中的路徑,VFS也許需要按照路徑結構重新創(chuàng)建該緩存,并加載inode節(jié)點。這通過查找inode節(jié)點實現(xiàn)。
            2、Inode節(jié)點對象
            一個獨立的目錄結構通常會有一個指向一個inode的指針。Inodes是文件系統(tǒng)的對象,例如普通文件,目錄,F(xiàn)IFO等。他們或者存在于磁盤上(快設備文件系統(tǒng))或者內存中(偽文件系統(tǒng))。被請求訪問的inode從磁盤加載道內存,在修改后再寫入磁盤。
            一個獨立的inode可以同時作為多個目錄結構的指針目標(如硬鏈接時會出現(xiàn)這種情況)。
            查找一個inode時,需要通過VFS對inode的父目錄inode調用looup()方法。該方法在inode所屬的具體文件系統(tǒng)中實現(xiàn)。一旦VFS 請求了目錄結構(同時inode),我們就可以通過open(2)打開文件,或者stat(2)查看inode數(shù)據(jù)。stat(2)操作很簡單,一旦 VFS獲得了目錄結構,它就察看inode數(shù)據(jù),并將其中某些數(shù)據(jù)傳給用戶空間。
            3、文件對象
            打開一個文件還需要其它的操作:獲取文件結構(內核實現(xiàn)的文件描述表)。最新分配的文件結構被初始化為一個指向目錄結構的指針和一組文件操作函數(shù)集合。這些數(shù)據(jù)從inode獲得。然后調用特定的文件系統(tǒng)實現(xiàn)的open()文件操作執(zhí)行相關的任務。這是VFS交換功能的一個實現(xiàn)。文件結構被加入進程的文件表述表。
            讀、寫和關閉文件(以及其它相關的VFS操作)通過用戶空間的文件描述表獲取對應的文件結構,然后調用請求的文件結構來實現(xiàn)需要得功能。一旦文件被打開,目錄結構將保持在使用狀態(tài),表示VFS inode處于被訪問狀態(tài)。

            二、注冊和加載文件系統(tǒng)
            注冊和注銷一個文件系統(tǒng)時,使用下面的API:
               #include <linux/fs.h>
               extern int register_filesystem(struct file_system_type *);
               extern int unregister_filesystem(struct file_system_type *);
            傳遞的參數(shù)file_system_type結構描述了注冊的文件系統(tǒng)。當生成將一個設備掛載到文件空間的一個目錄時,VFS將調用相應文件系統(tǒng)所實現(xiàn)的get_sb()方法。接著,被掛載點的目錄結構將被更新指向新文件系統(tǒng)的root inode節(jié)點。
            在/proc/filesystems中可以看到在內核中注冊的所有文件系統(tǒng)。
            1、file_system_type結構
            該結構對文件系統(tǒng)進行描述,在2.6.20內核中,其在include/linux/fs.h定義如下:
            struct file_system_type {
            const char *name;
            int fs_flags;
            int (*get_sb) (struct file_system_type *, int,
                     const char *, void *, struct vfsmount *);
            void (*kill_sb) (struct super_block *);
            struct module *owner;
            struct file_system_type * next;
            struct list_head fs_supers;
            struct lock_class_key s_lock_key;
            struct lock_class_key s_umount_key;
            };
            name:   文件系統(tǒng)類型名,如"ext2", "iso9660", "msdos"等
            fs_flags: 幾種文件系統(tǒng)flag標志(FS_REQUIRES_DEV, FS_NO_DCACHE等)
            get_sb:  加載(mount)新的文件系統(tǒng)實例時會調用的方法。sb指super block
            kill_sb: 卸載(unmount)文件系統(tǒng)實例時調用
            owner:  VFS內部使用,大多數(shù)情況下,應該被初始化為 THIS_MODULE
            next:  VFS內部使用,初始化為NULL
            s_lock_key:
            s_umount_key:
            get_sb參數(shù)如下:
            struct super_block *sb: superblock結構,該結構部分由vFS初始化,其余的在get_sb()方法中初始化
            int flags:  掛載標志
            const char *dev_name: 掛載的設備名
            void *data:  掛載屬性選項,通常為ASCII字符串
            int silent:  出錯時的處理方式
            get_sb()方法必須superblock中指定的塊設備是否包含該方法支持的文件系統(tǒng)。執(zhí)行成功,就返回指向superblock的指針,出錯則返回NULL
            s_op成員是get_sb中需要關注的項,它是一個指向結構"struct super_operations"的指針,該結構描述了文件系統(tǒng)的底層實現(xiàn)。
            通常,一個文件系統(tǒng)使用get_sb()的具體實現(xiàn)中的一個,并提供fill_super方法。具體方法如下:
            get_sb_bdev: 掛載塊設備上的文件系統(tǒng)
            get_sb_nodev:掛載無設備文件系統(tǒng)
            get_sb_single:掛載在掛載點之間共享實例的文件系統(tǒng)
            fill_super方法實現(xiàn)含有的變量如下:
            struct super_block *sb: super_block結構,由fill_super()初始化
            void *data:  掛載屬性選項,通常為ASCII字符串
            int silent:  出錯時的處理方式

            三、Superblock對象
            一個Superblock對象代表了一個掛載的文件系統(tǒng)。
            1、super_operations結構
            該結構描述了VFS操作文件系統(tǒng)的方式。在2.6.20內核中,其在include/linux/fs.h定義如下:
            struct super_operations {
                struct inode *(*alloc_inode)(struct super_block *sb);
            void (*destroy_inode)(struct inode *);
            void (*read_inode) (struct inode *);
             
                void (*dirty_inode) (struct inode *);
            int (*write_inode) (struct inode *, int);
            void (*put_inode) (struct inode *);
            void (*drop_inode) (struct inode *);
            void (*delete_inode) (struct inode *);
            void (*put_super) (struct super_block *);
            void (*write_super) (struct super_block *);
            int (*sync_fs)(struct super_block *sb, int wait);
            void (*write_super_lockfs) (struct super_block *);
            void (*unlockfs) (struct super_block *);
            int (*statfs) (struct dentry *, struct kstatfs *);
            int (*remount_fs) (struct super_block *, int *, char *);
            void (*clear_inode) (struct inode *);
            void (*umount_begin) (struct vfsmount *, int);
            int (*show_options)(struct seq_file *, struct vfsmount *);
            int (*show_stats)(struct seq_file *, struct vfsmount *);
            #ifdef CONFIG_QUOTA
            ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
            ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
            #endif
            };
            所有的方法調用時除非特別要求,不會持有任何鎖。這意味著,這些方法可以安全的阻塞。這些發(fā)放必須在進程的上下文中調用。(不能通過中斷句柄或者下半部bottom half調用——沒有進程上下文)
            alloc_inode: 該方法由inode_alloc調用,為inode結構分配空間和初始化。如果未定義該方法,將分配一個簡單的inode結構。通常,alloc_inode被用來分配一個包含inode結構的大型數(shù)據(jù)結構。
            destroy_inode: 該方法由destroy_inode調用,用以釋放為inode結構分配的資源。它只在alloc_inode方法被定義時有效,簡單的逆向執(zhí)行(undo)alloc_inode中的處理。
            read_inode: 該方法被用來從掛載的文件系統(tǒng)中讀取一個特定的inode。VFS設置inode結構中的i_ino成員來指示被讀取得inode。其它的成員由該方法設置。
            dirty_inode: VFS調用該方法來標記一個臟inode節(jié)點。
            write_inode: VFS調用該方法將inode結構協(xié)會磁盤。第二個參數(shù)標示使用同步寫還是異步方式,不是所有的文件系統(tǒng)都檢查該標記。
            put_inode: 在VFS的inode從cache中移除時調用。。
            drop_inode: 在最后一個對該inode節(jié)點的訪問操作被放棄時調用,該操作持有inode_lock自旋鎖。該方法必須或為空(NULL,通常意義上的Unix文件系統(tǒng)語義),或為"generic_delete_inode"(為不需要緩存inode的文件系統(tǒng),以使無論i_nlink為何值的情況下,都會調用"delete_inode")  "generic_delete_inode()"和曾經(jīng)在 put_inode()中使用的"force_delete"行為相似,但是不會存在"force_delete"方法的競爭。
            delete_inode: VFS調用該方法刪除一個inode節(jié)點。
            put_super; VFS調用該方法釋放一個superblock(如umount)。在持有superblock鎖時調用
            write_super: 載VFS superblock需要寫入磁盤時調用,該方法為可選。
            sync_fs: 在VFS寫一個superblock相關的所有inode節(jié)點時調用。第二個參數(shù)指示是否等待所有的寫操作完成后再執(zhí)行。可選。
            write_super_lockfs: 在VFS鎖住一個文件系統(tǒng)時調用,并強制進入一致狀態(tài)。該方法現(xiàn)在由邏輯卷管理器(LVM)使用。
            unlockfs; VFS調用該方法釋放文件系統(tǒng)的鎖,使其重新可寫。
            statfs:  在VFS需要獲得文件系統(tǒng)統(tǒng)計信息時調用。該方法調用需要獲得內核鎖。
            remount_fs: 在文件系統(tǒng)重新掛載時調用。該方法調用需要獲得內核鎖。
            clear_inode: 在VFS清除一個inode節(jié)點試調用。可選。
            umount_begin; 在VFS卸載文件系統(tǒng)時調用。
            //sync_inodes; VFS寫superblock關聯(lián)的臟數(shù)據(jù)時調用。 --2.6.20中取消
            show_options: 在VFS顯示/proc/<pid>/mounts的掛載參數(shù)時調用。
            show_stats:
            quota_read: VFS調用該方法讀取文件系統(tǒng)的配額文件。
            quota_write; VFS調用該方法寫入文件系統(tǒng)的配額文件。
            read_inode()方法負責填充i_op域,該域是一個指向inode_operations結構的指針,該結構描述了每個inodes的操作方法。

            四、inode對象

            inode是文件系統(tǒng)中的對象元素。

            1、inode_operations結構

            該結構描述了VFS如何操作文件系統(tǒng)中的inode。在2.6.20中定義如下:

            struct inode_operations {
             int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
             struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
             int (*link) (struct dentry *,struct inode *,struct dentry *);
             int (*unlink) (struct inode *,struct dentry *);
             int (*symlink) (struct inode *,struct dentry *,const char *);
             int (*mkdir) (struct inode *,struct dentry *,int);
             int (*rmdir) (struct inode *,struct dentry *);
             int (*mknod) (struct inode *,struct dentry *,int,dev_t);
             int (*rename) (struct inode *, struct dentry *,
               struct inode *, struct dentry *);
             int (*readlink) (struct dentry *, char __user *,int);
             void * (*follow_link) (struct dentry *, struct nameidata *);
             void (*put_link) (struct dentry *, struct nameidata *, void *);
             void (*truncate) (struct inode *);
             int (*permission) (struct inode *, int, struct nameidata *);
             int (*setattr) (struct dentry *, struct iattr *);
             int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
             int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
             ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
             ssize_t (*listxattr) (struct dentry *, char *, size_t);
             int (*removexattr) (struct dentry *, const char *);
             void (*truncate_range)(struct inode *, loff_t, loff_t);
            };

            所有方法除非特別要求,調用時不必持有鎖。

            create:  由open(2)和create(2)系統(tǒng)調用調用。只在需要支持常規(guī)文件時必須定義。獲得的目錄結構不能存在inode(如,消極entry.如果有,就不需要創(chuàng)建了)。也許還需要為該dentry和新創(chuàng)建的inode調用d_instantiate()。

            lookup:  在VFS需要從父目錄里查找一個inode時調用。查找的名字從dentry中獲得。該方法將找到的inode通過調用 d_add()插入到目錄結構中。結構中的i_count項增1。如果該名字的inode不存在,則在dentry中增加一個空的inode(該 dentryb被稱為消極dentry)

            link:  由link(2)系統(tǒng)調用調用,只在需要支持硬鏈接(hard link)時必須定義。和在create()方法中類似,需要調用d_instantiate()。

            ulink:  由ulink(2)系統(tǒng)調用調用,只在需要支持刪除inode時必須定義。

            symlink: 由symlink(2)系統(tǒng)調用調用,只在需要支持軟鏈接(symbolick link)時必須定義。和在create()方法中類似,需要調用d_instantiate()。

            mkdir:  由mkdir(2)系統(tǒng)調用調用,只在需要支持軟鏈接(symbolick link)時必須定義。和在create()方法中類似,需要調用d_instantiate()。

            rmdir:  由rmdir(2)系統(tǒng)調用調用,只在需要支持刪除子目錄時必須定義。

            mknod:  由mknode(2)系統(tǒng)調用用來為設備(字符或塊),命名管道或者套接字創(chuàng)建inode時調用,只在需要支持創(chuàng)建這類inode時必須定義。和在create()方法中類似,需要調用d_instantiate()。

            rename:  由rename(2)系統(tǒng)調用調用,將源inode和dentry(前兩個)改為目標inode和dentry(后兩個)的父目錄和文件名。

            readlink: 由readlink(2)系統(tǒng)調用調用,只在需要支持軟鏈接(symbolick link)時必須定義。

            follow_link: 由VFS調用,用來獲得一個軟鏈接所指向的inode,只在需要支持軟鏈接(symbolick link)時必須定義。該方法返回一個可以傳給put_link()方法的空指針。

            put_link: 由VFS調用,用來釋放由follow_link分配的資源。該方法的最后一個參數(shù)是由follow_up返回的一個空指針的值參。它在頁緩存不穩(wěn)定的文件系統(tǒng)(如,NFS)中應用。

            truncate: 由VFS調用,用來改變一個文件的大小。必須在該方法調用前用需要得大小來設置inode的i_size值。該方法被truncate(2)以及相關的系統(tǒng)調用調用。

            permission: VFS調用該方法檢查在POSIX類的文件系統(tǒng)上的訪問權限。

            serattr: VFS調用該方法設置文件的屬性。該方法被chmod(2)以及相關的系統(tǒng)調用調用。

            getattr: 獲得文件屬性。由stat(2)以及相關系統(tǒng)調用調用。

            setxattr: VFS調用該方法設置文件的擴展屬性信息。擴展屬性是inode相關的"name:value"對。該方法由setxattr(2)系統(tǒng)調用調用。

            getxattr; VFS調用該方法獲得給定文件擴展屬性的值。該方法由getxattr(2)系統(tǒng)調用調用。

            listxattr: VFS調用該方法列出給定文件的所有擴展屬性信息。該方法由listxattr(2)系統(tǒng)調用調用。

            removexattr: VFS調用該方法移除給定文件的所有擴展屬性信息。該方法由removexattr(2)系統(tǒng)調用調用。
            亚洲国产精品久久久久| 色诱久久久久综合网ywww| 免费观看成人久久网免费观看| 国产精品美女久久久久网| 欧美精品一本久久男人的天堂| 无码8090精品久久一区| 人妻久久久一区二区三区| 超级碰久久免费公开视频| 久久午夜无码鲁丝片秋霞| 久久er热视频在这里精品| 亚洲国产天堂久久综合| 成人国内精品久久久久影院| 亚洲人成无码www久久久| 久久国产乱子精品免费女| 欧美精品国产综合久久| 99久久99久久精品国产片| 日韩av无码久久精品免费| 日韩十八禁一区二区久久| 久久99精品国产| jizzjizz国产精品久久| 久久久精品人妻一区二区三区蜜桃| 国产成人久久精品麻豆一区| 久久人爽人人爽人人片AV| 婷婷久久精品国产| 久久久人妻精品无码一区| 久久成人国产精品二三区| 久久人人爽爽爽人久久久| 77777亚洲午夜久久多喷| 亚洲国产成人久久综合野外| 久久久久久无码国产精品中文字幕 | 亚洲v国产v天堂a无码久久| 久久91综合国产91久久精品| 精品无码久久久久国产| 久久国产劲爆AV内射—百度| 久久精品国产欧美日韩99热| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 99久久精品国产麻豆| 99久久精品国内| 国产精品99久久久久久www| 国产精品激情综合久久| 久久黄色视频|