天天看點

struct inode 和 struct filefile結構體和inode結構體 

*索引節點對象由inode結構體表示,定義檔案在linux/fs.h中

*/

struct inode {

        struct hlist_node       i_hash;              /* 哈希表 */

        struct list_head        i_list;              /* 索引節點連結清單 */

        struct list_head        i_dentry;            /* 目錄項連結清單 */

        unsigned long           i_ino;               /* 節點号 */

        atomic_t                i_count;             /* 引用記數 */

        umode_t                 i_mode;              /* 通路權限控制 */

        unsigned int            i_nlink;             /* 硬連結數 */

        uid_t                   i_uid;               /* 使用者id */

        gid_t                   i_gid;               /* 使用者id組 */

        kdev_t                  i_rdev;              /* 實裝置辨別符 */

        loff_t                  i_size;              /* 以位元組為機關的檔案大小 */

        struct timespec         i_atime;             /* 最後通路時間 */

        struct timespec         i_mtime;             /* 最後修改(modify)時間 */

        struct timespec         i_ctime;             /* 最後改變(change)時間 */

        unsigned int            i_blkbits;           /* 以位為機關的塊大小 */

        unsigned long           i_blksize;           /* 以位元組為機關的塊大小 */

        unsigned long           i_version;           /* 版本号 */

        unsigned long           i_blocks;            /* 檔案的塊數 */

        unsigned short          i_bytes;             /* 使用的位元組數 */

        spinlock_t              i_lock;              /* 自旋鎖 */

        struct rw_semaphore     i_alloc_sem;         /* 索引節點信号量 */

        struct inode_operations *i_op;               /* 索引節點操作表 */

        struct file_operations  *i_fop;              /* 預設的索引節點操作 */

        struct super_block      *i_sb;               /* 相關的超級塊 */

        struct file_lock        *i_flock;            /* 檔案鎖連結清單 */

        struct address_space    *i_mapping;          /* 相關的位址映射 */

        struct address_space    i_data;              /* 裝置位址映射 */

        struct dquot            *i_dquot[MAXQUOTAS]; /* 節點的磁盤限額 */

        struct list_head        i_devices;           /* 塊裝置連結清單 */

        struct pipe_inode_info  *i_pipe;             /* 管道資訊 */

        struct block_device     *i_bdev;             /* 塊裝置驅動 */

        unsigned long           i_dnotify_mask;      /* 目錄通知掩碼 */

        struct dnotify_struct   *i_dnotify;          /* 目錄通知 */

        unsigned long           i_state;             /* 狀态标志 */

        unsigned long           dirtied_when;        /* 首次修改時間 */

        unsigned int            i_flags;             /* 檔案系統标志 */

        unsigned char           i_sock;              /* 可能是個套接字吧 */

        atomic_t                i_writecount;        /* 寫者記數 */

        void                    *i_security;         /* 安全子產品 */

        __u32                   i_generation;        /* 索引節點版本号 */

        union {

                void            *generic_ip;         /* 檔案特殊資訊 */

        } u;

};

/*

*索引節點的操作inode_operations定義在linux/fs.h中

struct inode_operations {

        int (*create) (struct inode *, struct dentry *,int);

        /*VFS通過系統調用create()和open()來調用該函數,進而為dentry對象建立一個新的索引節點。在建立時使用mode制定初始模式*/

        struct dentry * (*lookup) (struct inode *, struct dentry *);

        /*該韓式在特定目錄中尋找索引節點,該索引節點要對應于dentry中給出的檔案名*/

        int (*link) (struct dentry *, struct inode *, struct dentry *);

        /*該函數被系統調用link()電泳,用來建立硬連接配接。硬連結名稱由dentry參數指定,連接配接對象是dir目錄中ld_dentry目錄想所代表的檔案*/

        int (*unlink) (struct inode *, struct dentry *);

        /*該函數被系統調用unlink()調用,從目錄dir中删除由目錄項dentry制動的索引節點對象*/

        int (*symlink) (struct inode *, struct dentry *, const char *);

        /*該函數被系統電泳symlik()調用,建立符号連接配接,該符号連接配接名稱由symname指定,連接配接對象是dir目錄中的dentry目錄項*/

        int (*mkdir) (struct inode *, struct dentry *, int);

        /*該函數被mkdir()調用,建立一個新魯姆。建立時使用mode制定的初始模式*/

        int (*rmdir) (struct inode *, struct dentry *);

        /*該函數被系統調用rmdir()調用,删除dir目錄中的dentry目錄項代表的檔案*/

        int (*mknod) (struct inode *, struct dentry *, int, dev_t);

        /*該函數被系統調用mknod()調用,建立特殊檔案(裝置檔案、命名管道或套接字)。要建立的檔案放在dir目錄中,其目錄項問dentry,關聯的裝置為rdev,初始權限由mode指定*/

        int (*rename) (struct inode *, struct dentry *,

                       struct inode *, struct dentry *);

        /*VFS調用該函數來移動檔案。檔案源路徑在old_dir目錄中,源檔案由old_dentry目錄項所指定,目标路徑在new_dir目錄中,目标檔案由new_dentry指定*/

        int (*readlink) (struct dentry *, char *, int);

        /*該函數被系統調用readlink()調用,拷貝資料到特定的緩沖buffer中。拷貝的資料來自dentry指定的符号連結,最大拷貝大小可達到buflen位元組*/

        int (*follow_link) (struct dentry *, struct nameidata *);

        /*該函數由VFS調用,從一個符号連接配接查找他指向的索引節點,由dentry指向的連接配接被解析*/

        int (*put_link) (struct dentry *, struct nameidata *);

        /*在follow_link()調用之後,該函數由vfs調用進行清楚工作*/

        void (*truncate) (struct inode *);

        /*該函數由VFS調用,修改檔案的大小,在調用之前,索引節點的i_size項必須被設定成預期的大小*/

        int (*permission) (struct inode *, int);

        /*該函數用來檢查給低昂的inode所代表的檔案是否允許特定的通路模式,如果允許特定的通路模式,傳回0,否則傳回負值的錯誤碼。多數檔案系統都将此區域設定為null,使用VFS提供的通用方法進行檢查,這種檢查操作僅僅比較索引及诶但對象中的通路模式位是否和mask一緻,比較複雜的系統,比如支援通路控制鍊(ACL)的檔案系統,需要使用特殊的permission()方法*/

        int (*setattr) (struct dentry *, struct iattr *);

        /*該函數被notify_change調用,在修改索引節點之後,通知發生了改變事件*/

        int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);

        /*在通知索引節點需要從磁盤中更新時,VFS會調用該函數*/

        int (*setxattr) (struct dentry *, const char *,

                         const void *, size_t, int);

        /*該函數由VFS調用,向dentry指定的檔案設定擴充屬性,屬性名為name,值為value*/

        ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);

        /*該函數被VFS調用,向value中拷貝給定檔案的擴充屬性name對應的數值*/

        ssize_t (*listxattr) (struct dentry *, char *, size_t);

        /*該函數将特定檔案所有屬性别表拷貝到一個緩沖清單中*/

        int (*removexattr) (struct dentry *, const char *);

        /*該函數從給定檔案中删除指定的屬性*/

1、struct inode──字元裝置驅動相關的重要結構介紹

核心中用inode結構表示具體的檔案,而用file結構表示打開的檔案描述符。Linux2.6.27核心中,inode結構體具體定義如下:

struct hlist_node    i_hash;

struct list_head    i_list;

struct list_head    i_sb_list;

struct list_head    i_dentry;

unsigned long        i_ino;

atomic_t        i_count;

unsigned int        i_nlink;

uid_t            i_uid;

gid_t            i_gid;

 dev_t            i_rdev;   //該成員表示裝置檔案的inode結構,它包含了真正的裝置編号。

u64            i_version;

loff_t            i_size;

#ifdef __NEED_I_SIZE_ORDERED

seqcount_t        i_size_seqcount;

#endif

struct timespec        i_atime;

struct timespec        i_mtime;

struct timespec        i_ctime;

unsigned int        i_blkbits;

blkcnt_t        i_blocks;

unsigned short          i_bytes;

umode_t            i_mode;

spinlock_t        i_lock;    /* i_blocks, i_bytes, maybe i_size */

struct mutex        i_mutex;

struct rw_semaphore    i_alloc_sem;

const struct inode_operations    *i_op;

const struct file_operations    *i_fop;    /* former ->i_op->default_file_ops */

struct super_block    *i_sb;

struct file_lock    *i_flock;

struct address_space    *i_mapping;

struct address_space    i_data;

#ifdef CONFIG_QUOTA

struct dquot        *i_dquot[MAXQUOTAS];

struct list_head    i_devices;

union {

struct pipe_inode_info    *i_pipe;

struct block_device    *i_bdev;

 struct cdev        *i_cdev; //該成員表示字元裝置的核心的 内部結構。當inode指向一個字元裝置檔案時,該成員包含了指向struct cdev結構的指針,其中cdev結構是字元裝置結構體。

int            i_cindex;

__u32            i_generation;

#ifdef CONFIG_DNOTIFY

unsigned long        i_dnotify_mask; /* Directory notify events */

struct dnotify_struct    *i_dnotify; /* for directory notifications */

#ifdef CONFIG_INOTIFY

struct list_head    inotify_watches; /* watches on this inode */

struct mutex        inotify_mutex;    /* protects the watches list */

unsigned long        i_state;

unsigned long        dirtied_when;    /* jiffies of first dirtying */

unsigned int        i_flags;

atomic_t        i_writecount;

#ifdef CONFIG_SECURITY

void            *i_security;

void            *i_private; /* fs or device private pointer */

2、struct file ──字元裝置驅動相關重要結構

檔案結構 代表一個打開的檔案描述符,它不是專門給驅動程式使用的,系統中每一個打開的檔案在核心中都有一個關聯的struct file。它由核心在open時建立,并傳遞給在檔案上操作的任何函數,知道最後關閉。當檔案的所有執行個體都關閉之後,核心釋放這個資料結構。

struct file {

* fu_list becomes invalid after file_free is called and queued via

* fu_rcuhead for RCU freeing

struct list_head    fu_list;

struct rcu_head     fu_rcuhead;

} f_u;

struct path        f_path;

#define f_dentry    f_path.dentry   //該成員是對應的 目錄結構 。

#define f_vfsmnt    f_path.mnt

const struct file_operations    *f_op;  //該操作 是定義檔案關聯的操作的。核心在執行open時對這個 指針指派。

atomic_long_t        f_count;

 unsigned int         f_flags; 

//該成員是檔案标志。

mode_t            f_mode;

loff_t            f_pos;

struct fown_struct    f_owner;

unsigned int        f_uid, f_gid;

struct file_ra_state    f_ra;

u64            f_version;

void            *f_security;

/* needed for tty driver, and maybe others */

void            *private_data;//該成員是系統調用時儲存狀态資訊非常有用的資源。

#ifdef CONFIG_EPOLL

/* Used by fs/eventpoll.c to link all the hooks to this file */

struct list_head    f_ep_links;

spinlock_t        f_ep_lock;

#endif /* #ifdef CONFIG_EPOLL */

struct address_space    *f_mapping;

#ifdef CONFIG_DEBUG_WRITECOUNT

unsigned long f_mnt_write_state;

----------------------------------------------------------------------------

(1)struct file結構體定義在include/linux/fs.h中定義。檔案結構體代表一個打開的檔案,系統中的每個打開的檔案在核心空間都有一個關聯的 struct file。它由核心在打開檔案時建立,并傳遞給在檔案上進行操作的任何函數。在檔案的所有執行個體都關閉後,核心釋放這個資料結構。在核心建立和驅動源碼中,struct file的指針通常被命名為file或filp。如下所示:

        union {

             struct list_head fu_list; 檔案對象連結清單指針linux/include/linux/list.h

             struct rcu_head fu_rcuhead; RCU(Read-Copy Update)是Linux 2.6核心中新的鎖機制

        } f_u;

        struct path f_path;  包含dentry和mnt兩個成員,用于确定檔案路徑

        #define f_dentry  f_path.dentry  f_path的成員之一,目前檔案的dentry結構

        #define f_vfsmnt  f_path.mnt  表示目前檔案所在檔案系統的挂載根目錄

        const struct file_operations *f_op; 與該檔案相關聯的操作函數

        atomic_t  f_count; 檔案的引用計數(有多少程序打開該檔案)

        unsigned int  f_flags;  對應于open時指定的flag

        mode_t  f_mode; 讀寫模式:open的mod_t mode參數

        off_t  f_pos; 該檔案在目前程序中的檔案偏移量

        struct fown_struct f_owner; 該結構的作用是通過信号進行I/O時間通知的資料。

        unsigned int  f_uid, f_gid; 檔案所有者id,所有者組id

        struct file_ra_state f_ra;  在linux/include/linux/fs.h中定義,檔案預讀相關

        unsigned long f_version;

        #ifdef CONFIG_SECURITY

             void  *f_security;

        #endif

        /* needed for tty driver, and maybe others */

        void *private_data;

        #ifdef CONFIG_EPOLL

        /* Used by fs/eventpoll.c to link all the hooks to this file */

        struct list_head f_ep_links;

        spinlock_t f_ep_lock;

       #endif /* #ifdef CONFIG_EPOLL */

       struct address_space *f_mapping;

(2)struct dentry

dentry 的中文名稱是目錄項,是Linux檔案系統中某個索引節點(inode)的連結。這個索引節點可以是檔案,也可以是目錄。inode(可了解為ext2 inode)對應于實體磁盤上的具體對象,dentry是一個記憶體實體,其中的d_inode成員指向對應的inode。也就是說,一個inode可以在運作的時候連結多個dentry,而d_count記錄了這個連結的數量。

struct dentry {

        atomic_t d_count; 目錄項對象使用計數器,可以有未使用态,使用态和負狀态                                           

        unsigned int d_flags; 目錄項标志

        struct inode * d_inode; 與檔案名關聯的索引節點

        struct dentry * d_parent; 父目錄的目錄項對象

        struct list_head d_hash; 散清單表項的指針

        struct list_head d_lru; 未使用連結清單的指針

        struct list_head d_child; 父目錄中目錄項對象的連結清單的指針

        struct list_head d_subdirs;對目錄而言,表示子目錄目錄項對象的連結清單

        struct list_head d_alias; 相關索引節點(别名)的連結清單

        int d_mounted; 對于安裝點而言,表示被安裝檔案系統根項

        struct qstr d_name; 檔案名

        unsigned long d_time; /* used by d_revalidate */

        struct dentry_operations *d_op; 目錄項方法

        struct super_block * d_sb; 檔案的超級塊對象

        vunsigned long d_vfs_flags;

        void * d_fsdata;與檔案系統相關的資料

        unsigned char d_iname [DNAME_INLINE_LEN]; 存放短檔案名

(3)索引節點對象由inode結構體表示,定義檔案在linux/fs.h中。

        struct hlist_node       i_hash; 哈希表

        struct list_head        i_list;   索引節點連結清單

        struct list_head        i_dentry; 目錄項連結清單

        unsigned long           i_ino;  節點号

        atomic_t                i_count; 引用記數

        umode_t                 i_mode; 通路權限控制

        unsigned int            i_nlink; 硬連結數

        uid_t                   i_uid;  使用者id

        gid_t                   i_gid;  使用者id組

        kdev_t                  i_rdev; 實裝置辨別符

        loff_t                  i_size;  以位元組為機關的檔案大小

        struct timespec         i_atime; 最後通路時間

        struct timespec         i_mtime; 最後修改(modify)時間

        struct timespec         i_ctime; 最後改變(change)時間

        unsigned int            i_blkbits; 以位為機關的塊大小

        unsigned long           i_blksize; 以位元組為機關的塊大小

        unsigned long           i_version; 版本号

        unsigned long           i_blocks; 檔案的塊數

        unsigned short          i_bytes; 使用的位元組數

        spinlock_t              i_lock; 自旋鎖

        struct rw_semaphore     i_alloc_sem; 索引節點信号量

        struct inode_operations *i_op; 索引節點操作表

        struct file_operations  *i_fop; 預設的索引節點操作

        struct super_block      *i_sb; 相關的超級塊

        struct file_lock        *i_flock; 檔案鎖連結清單

        struct address_space    *i_mapping; 相關的位址映射

        struct address_space    i_data; 裝置位址映射

        struct dquot            *i_dquot[MAXQUOTAS];節點的磁盤限額

        struct list_head        i_devices; 塊裝置連結清單

        struct pipe_inode_info  *i_pipe; 管道資訊

        struct block_device     *i_bdev; 塊裝置驅動

        unsigned long           i_dnotify_mask;目錄通知掩碼

        struct dnotify_struct   *i_dnotify; 目錄通知

        unsigned long           i_state; 狀态标志

        unsigned long           dirtied_when;首次修改時間

        unsigned int            i_flags; 檔案系統标志

        unsigned char           i_sock; 套接字

        atomic_t                i_writecount; 寫者記數

        void                    *i_security; 安全子產品

        __u32                   i_generation; 索引節點版本号

                void            *generic_ip;檔案特殊資訊

        } u;

      inode 譯成中文就是索引節點。每個儲存設備或儲存設備的分區(儲存設備是硬碟、軟碟、U盤 ... ... )被格式化為檔案系統後,應該有兩部份,一部份是inode,另一部份是Block,Block是用來存儲資料用的。而inode呢,就是用來存儲這些資料的資訊,這些資訊包括檔案大小、屬主、歸屬的使用者組、讀寫權限等。inode為每個檔案進行資訊索引,是以就有了inode的數值。作業系統根據指令,能通過inode值最快的找到相對應的檔案。

      做個比喻,比如一本書,儲存設備或分區就相當于這本書,Block相當于書中的每一頁,inode 就相當于這本書前面的目錄,一本書有很多的内容,如果想查找某部份的内容,我們可以先查目錄,通過目錄能最快的找到我們想要看的内容。

      當我們用ls 檢視某個目錄或檔案時,如果加上-i 參數,就可以看到inode節點了;比如ls -li lsfile.sh ,最前面的數值就是inode資訊

繼續閱讀