linux fs

来源:互联网 发布:数据库建库 编辑:程序博客网 时间:2024/06/05 00:38
在内存中, 每个文件都有一个dentry(目录项)和inode(索引节点)结构,dentry记录着文件名,上级目录等信息,正是它形成了我们所看到的树状结构;而有关该文件的组织和管理的信息主要存放inode里面,它记录着文件在存储介质上的位置与分布。

struct dentry {
    /* RCU lookup touched fields */
    unsigned int d_flags;        /* protected by d_lock */
    seqcount_t d_seq;        /* per dentry seqlock */
    struct hlist_bl_node d_hash;    /* lookup hash list */
    struct dentry *d_parent;    /* parent directory */
    struct qstr d_name;
    struct inode *d_inode;        /* Where the name belongs to - NULL is
                     * negative */
    unsigned char d_iname[DNAME_INLINE_LEN];    /* small names */

    /* Ref lookup also touches following */
    unsigned int d_count;        /* protected by d_lock */
    spinlock_t d_lock;        /* per dentry lock */
    const struct dentry_operations *d_op;
    struct super_block *d_sb;    /* The root of the dentry tree */
    unsigned long d_time;        /* used by d_revalidate */
    void *d_fsdata;            /* fs-specific data */

    struct list_head d_lru;        /* LRU list */
    /*
     * d_child and d_rcu can share memory
     */
    union {
        struct list_head d_child;    /* child of parent list */
         struct rcu_head d_rcu;
    } d_u;
    struct list_head d_subdirs;    /* our children */
    struct hlist_node d_alias;    /* inode alias list */
};
所有的dentry用d_parent和d_child连接起来,就形成了我们熟悉的树状结构。


struct inode {
    umode_t            i_mode;
    unsigned short        i_opflags;
    kuid_t            i_uid;
    kgid_t            i_gid;
    unsigned int        i_flags;

    const struct inode_operations    *i_op;
    struct super_block    *i_sb;
    struct address_space    *i_mapping;

    /* Stat data, not accessed from path walking */
    unsigned long        i_ino;
    /*
     * Filesystems may only read i_nlink directly.  They shall use the
     * following functions for modification:
     *
     *    (set|clear|inc|drop)_nlink
     *    inode_(inc|dec)_link_count
     */
    union {
        const unsigned int i_nlink;
        unsigned int __i_nlink;
    };
    dev_t            i_rdev;
    loff_t            i_size;
    struct timespec        i_atime;
    struct timespec        i_mtime;
    struct timespec        i_ctime;
    spinlock_t        i_lock;    /* i_blocks, i_bytes, maybe i_size */
    unsigned short          i_bytes;
    unsigned int        i_blkbits;
    blkcnt_t        i_blocks;

    /* Misc */
    unsigned long        i_state;
    struct mutex        i_mutex;

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

    struct hlist_node    i_hash;
    struct list_head    i_wb_list;    /* backing dev IO list */
    struct list_head    i_lru;        /* inode LRU list */
    struct list_head    i_sb_list;
    union {
        struct hlist_head    i_dentry;
        struct rcu_head        i_rcu;
    };
    u64            i_version;
    atomic_t        i_count;
    atomic_t        i_dio_count;
    atomic_t        i_writecount;
    const struct file_operations    *i_fop;    /* former ->i_op->default_file_ops */
    struct file_lock    *i_flock;
    struct address_space    i_data;

    struct list_head    i_devices;
    union {
        struct pipe_inode_info    *i_pipe;
        struct block_device    *i_bdev;
        struct cdev        *i_cdev;
    };

    __u32            i_generation;

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

inode代表的是物理意义上的文件,通过inode可以得到一个数组(le32 i_data[15]),这个数组记录了文件内容的位置,如该文件位于硬盘的第3,8,10块,那么这个数组的内容就是3,8,10。其索引节点号inode->i_ino,在同一个文件系统中是唯一的,内核只要根据i_ino,就可以计算出它对应的inode在介质上的位置。就硬盘来说,根据i_ino就可以计算出它对应的inode属于哪个块(block),从而找到相应的inode结构。但仅仅用inode还是无法描述出所有的文件系统,对于某一种特定的文件系统而言,比如ext3,在内存中用ext3_inode_info描述。他是一个包含inode的"容器"。

struct ext3_inode_info {
    __le32    i_data[15];    /* unconverted */
    __u32    i_flags;

    ext3_fsblk_t    i_file_acl;
    __u32    i_dir_acl;
    __u32    i_dtime;

    __u32    i_block_group;
    unsigned long    i_state_flags;    /* Dynamic state flags for ext3 */

    /* block reservation info */
    struct ext3_block_alloc_info *i_block_alloc_info;

    __u32    i_dir_start_lookup;

    struct list_head i_orphan;    /* unlinked but open inodes */

    loff_t    i_disksize;

    /* on-disk additional length */
    __u16 i_extra_isize;


    struct mutex truncate_mutex;

    atomic_t i_sync_tid;
    atomic_t i_datasync_tid;

    struct inode vfs_inode;
};

以一个有100 block的硬盘为例,一个文件系统的组织布局大致如下图。位图区中的每一位表示每一个相应的对象有没有被使用。


内核中用inode结构表示具体的文件,而用file结构表示打开的文件描述符。

还有文件系统源码中经常用到的 file结构。文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。

struct file {
    
    struct path        f_path;
#define f_dentry    f_path.dentry
#define f_vfsmnt    f_path.mnt
    const struct file_operations    *f_op;

    /*
     * Protects f_ep_links, f_flags, f_pos vs i_size in lseek SEEK_CUR.
     * Must not be taken from IRQ context.
     */
    spinlock_t        f_lock;
#ifdef CONFIG_SMP
    int            f_sb_list_cpu;
#endif
    atomic_long_t        f_count;
    unsigned int         f_flags;
    fmode_t            f_mode;
    loff_t            f_pos;
    struct fown_struct    f_owner;
    const struct cred    *f_cred;
    struct file_ra_state    f_ra;

    u64            f_version;

    /* needed for tty driver, and maybe others */
    void            *private_data;
};

其中f_op就指向的是具体对该文件进行操作的函数。

其中 struct path {
        struct vfsmount *mnt;
        struct dentry *dentry;
};
struct vfsmount *mnt的作用是指出该文件的已安装的文件系统,
struct dentry *dentry是与文件相关的目录项对象。


我们谈到目录项和索引节点时,有两种含义。一种是在存储介质(硬盘)中的(如ext3_inode),一种是在内存中的,后者是根据在前者生成的。内存中的表示就是dentry和inode,它是VFS中的一层,不管什么样的文件系统,最后在内存中描述它的都是dentry和inode结构。我们使用不同的文件系统,就是将它们各自的文件信息都抽象到dentry和inode中去。这样对于高层来说,我们就可以不关心底层的实现,我们使用的都是一系列标准的函数调用。这就是VFS的精髓,实际上就是面向对象。

我们在进程中打开一个文件F,实际上就是要在内存中建立F的dentry,和inode结构,并让它们与进程结构联系来,把VFS中定义的接口给接起来。


一张更详细的图:


引用:

http://blog.chinaunix.net/uid-26557245-id-3432038.html

http://blog.csdn.net/wangchaoxjtuse/article/details/6036684

http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html

http://www.cnblogs.com/guguli/p/4556445.html


0 0