socket fs(1)

来源:互联网 发布:周末午夜光明知乎 编辑:程序博客网 时间:2024/06/06 02:44
/*******************************************************/
sock_init函数的主要功能是赋值全局变量sock_mnt:
static struct vfsmount *sock_mnt __read_mostly;
core_initcall(sock_init);    /* early initcall */

static int __init sock_init(void)
{
    int err;

    /*
     *      Initialize sock SLAB cache.
     */
    sk_init();

    /*
     *      Initialize skbuff SLAB cache
     */
    skb_init();

    /*
     *      Initialize the protocols module.
     */
    init_inodecache();

    err = register_filesystem(&sock_fs_type);

    sock_mnt = kern_mount(&sock_fs_type);

    /* The real protocol initialization is performed in later initcalls.
     */
    netfilter_init();

    return err;
}
函数sock_init里主要是相关结构体slab的初始化和文件系统相关的操作。

/*************************************************************************************/
/*这里首先涉及的数据类型为file_system_type*/
crash> file_system_type
struct file_system_type {
    const char *name;
    int fs_flags;
    struct dentry *(*mount)(struct file_system_type *, int, const char *, void *);
    void (*kill_sb)(struct super_block *);
    struct module *owner;
    struct file_system_type *next;
    struct hlist_head fs_supers;
    struct lock_class_key s_lock_key;
    struct lock_class_key s_umount_key;
    struct lock_class_key s_vfs_rename_key;
    struct lock_class_key i_lock_key;
    struct lock_class_key i_mutex_key;
    struct lock_class_key i_mutex_dir_key;
}
SIZE: 28
/*sockfs的文件系统类型为sock_fs_type:主要的函数为mount*/
static struct file_system_type sock_fs_type = {
    .name =        "sockfs",
    .mount =    sockfs_mount,
    .kill_sb =    kill_anon_super,
};

/**
 *    register_filesystem - register a new filesystem
 *    @fs: the file system structure
 *
 *    Adds the file system passed to the list of file systems the kernel
 *    is aware of for mount and other syscalls. Returns 0 on success,
 *    or a negative errno code on an error.
 *
 *    The &struct file_system_type that is passed is linked into the kernel
 *    structures and must not be freed until the file system has been
 *    unregistered.
 */
int register_filesystem(struct file_system_type * fs)
{
    int res = 0;
    struct file_system_type ** p;

    BUG_ON(strchr(fs->name, '.'));
    if (fs->next)
        return -EBUSY;
    write_lock(&file_systems_lock);
    p = find_filesystem(fs->name, strlen(fs->name));
    if (*p)
        res = -EBUSY;
    else
        *p = fs;/*使用二级指针,到这里才赋值到file_system_type全局变量*/
    write_unlock(&file_systems_lock);
    return res;
}
static struct file_system_type *file_systems;
/*根据file_systems可以找到所有的file system type.*/



/*************************************************************************************/
#define kern_mount(type) kern_mount_data(type, NULL)

struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
    struct vfsmount *mnt;
    mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
    if (!IS_ERR(mnt)) {
        /*
         * it is a longterm mount, don't release mnt until
         * we unmount before file sys is unregistered
        */
        mnt_make_longterm(mnt);
    }
    return mnt;
}

/*总的数据结构有关vfsmount: dentry and super_block*/
crash> vfsmount
struct vfsmount {
    struct dentry *mnt_root;
    struct super_block *mnt_sb;
    int mnt_flags;
}

struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
    struct mount *mnt;
    struct dentry *root;

    if (!type)
        return ERR_PTR(-ENODEV);
    /*首先得到结构体mount*/
    mnt = alloc_vfsmnt(name);
    if (!mnt)
        return ERR_PTR(-ENOMEM);

    if (flags & MS_KERNMOUNT)
        mnt->mnt.mnt_flags = MNT_INTERNAL;
    /*根据注册的文件系统类型得到dentry*/
    root = mount_fs(type, flags, name, data);
    if (IS_ERR(root)) {
        free_vfsmnt(mnt);
        return ERR_CAST(root);
    }
    /*根据mount赋值vfsmount,并返回结构体vfsmount*/
    mnt->mnt.mnt_root = root;
    mnt->mnt.mnt_sb = root->d_sb;
    mnt->mnt_mountpoint = mnt->mnt.mnt_root;
    mnt->mnt_parent = mnt;
    br_write_lock(vfsmount_lock);
    list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts);
    br_write_unlock(vfsmount_lock);
    return &mnt->mnt;
}

/*vfs_kern_mount -> alloc_vfsmnt引入了数据结构mount, vfsmount是mount的一个成员*/
static struct mount *alloc_vfsmnt(const char *name)
{
    struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
    if (mnt) {
    ---;
    }
    return mnt;
}
crash> struct mount
struct mount {
    struct list_head mnt_hash;
    struct mount *mnt_parent;
    struct dentry *mnt_mountpoint;
    struct vfsmount mnt;
    struct mnt_pcp *mnt_pcp;
    atomic_t mnt_longterm;
    struct list_head mnt_mounts;
    struct list_head mnt_child;
    struct list_head mnt_instance;
    const char *mnt_devname;
    struct list_head mnt_list;
    struct list_head mnt_expire;
    struct list_head mnt_share;
    struct list_head mnt_slave_list;
    struct list_head mnt_slave;
    struct mount *mnt_master;
    struct mnt_namespace *mnt_ns;
    struct hlist_head mnt_fsnotify_marks;
    __u32 mnt_fsnotify_mask;
    int mnt_id;
    int mnt_group_id;
    int mnt_expiry_mark;
    int mnt_pinned;
    int mnt_ghosts;
}
SIZE: 140


/*vfs_kern_mount -> mount_fs 引入了数据结构dentry, vfsmount是mount的一个成员
 *这里调用函数sockfs_mount生成了 dentry, super_block and inode.
 */
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
    struct dentry *root;
    struct super_block *sb;
    root = type->mount(type, flags, name, data);
    if (IS_ERR(root)) {
        error = PTR_ERR(root);
        goto out_free_secdata;
    }
    sb = root->d_sb;
    return root;
}

/* super_block: Stores information concerning a mounted filesystem.
 * For disk-based filesystems, this object usually corresponds to a
 * filesystem control block stored on disk.[该信息存在磁盘上]
 * super_block是怎样创建的?[创建一个,然后加入到链表super_blocks中]
 * sget(file_system_type, ,) -> alloc_super(file_system_type) -> list_add_tail(&s->s_list, &super_blocks);
 *
/
crash> super_block
struct super_block {
    struct list_head s_list;
    dev_t s_dev;
    unsigned char s_dirt;
    unsigned char s_blocksize_bits;
    unsigned long s_blocksize;
    loff_t s_maxbytes;
    struct file_system_type *s_type;
    const struct super_operations *s_op;
    const struct dquot_operations *dq_op;
    const struct quotactl_ops *s_qcop;
    const struct export_operations *s_export_op;
    unsigned long s_flags;
    unsigned long s_magic;
    struct dentry *s_root;
    struct rw_semaphore s_umount;
    struct mutex s_lock;
    int s_count;
    atomic_t s_active;
    const struct xattr_handler **s_xattr;
    struct list_head s_inodes;
    struct hlist_bl_head s_anon;
    struct list_head *s_files;
    struct list_head s_mounts;
    struct list_head s_dentry_lru;
    int s_nr_dentry_unused;
    spinlock_t s_inode_lru_lock;
    struct list_head s_inode_lru;
    int s_nr_inodes_unused;
    struct block_device *s_bdev;
    struct backing_dev_info *s_bdi;
    struct mtd_info *s_mtd;
    struct hlist_node s_instances;
    struct quota_info s_dquot;
    int s_frozen;
    wait_queue_head_t s_wait_unfrozen;
    char s_id[32];
    u8 s_uuid[16];
    void *s_fs_info;
    unsigned int s_max_links;
    fmode_t s_mode;
    u32 s_time_gran;
    struct mutex s_vfs_rename_mutex;
    char *s_subtype;
    char *s_options;
    const struct dentry_operations *s_d_op;
    int cleancache_poolid;
    struct shrinker s_shrink;
    atomic_long_t s_remove_count;
    int s_readonly_remount;
}
SIZE: 576


static struct dentry *sockfs_mount(struct file_system_type *fs_type,
             int flags, const char *dev_name, void *data)
{
    return mount_pseudo(fs_type, "socket:", &sockfs_ops,
        &sockfs_dentry_operations, SOCKFS_MAGIC);
}

struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
    const struct super_operations *ops,
    const struct dentry_operations *dops, unsigned long magic)
{
    /*先得到super_block*/    
    struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
    struct dentry *dentry;
    struct inode *root;
    struct qstr d_name = {.name = name, .len = strlen(name)};

    if (IS_ERR(s))
        return ERR_CAST(s);

    s->s_flags = MS_NOUSER;
    s->s_maxbytes = MAX_LFS_FILESIZE;
    s->s_blocksize = PAGE_SIZE;
    s->s_blocksize_bits = PAGE_SHIFT;
    s->s_magic = magic;
    s->s_op = ops ? ops : &simple_super_operations;
    s->s_time_gran = 1;
    /*根据super_block得到inode*/
    root = new_inode(s);
    if (!root)
        goto Enomem;
    /*
     * since this is the first inode, make it number 1. New inodes created
     * after this must take care not to collide with it (by passing
     * max_reserved of 1 to iunique).
     */
    root->i_ino = 1;
    root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
    root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
    /*根据super_block得到dentry*/
    dentry = __d_alloc(s, &d_name);
    if (!dentry) {
        iput(root);
        goto Enomem;
    }
    d_instantiate(dentry, root);
    s->s_root = dentry;
    s->s_d_op = dops;
    s->s_flags |= MS_ACTIVE;
    return dget(s->s_root);

Enomem:
    deactivate_locked_super(s);
    return ERR_PTR(-ENOMEM);
}


/**
 *    new_inode     - obtain an inode
 *    @sb: superblock
 *
 *    Allocates a new inode for given superblock.
 *
 *    new_inode_pseudo     - obtain an inode
 *    @sb: superblock
 *
 *    Allocates a new inode for given superblock.
 *    Inode wont be chained in superblock s_inodes list
 */
struct inode *new_inode(struct super_block *sb)
{
    struct inode *inode;

    spin_lock_prefetch(&inode_sb_list_lock);

    inode = new_inode_pseudo(sb);
    if (inode)
        inode_sb_list_add(inode);
    return inode;
}

/*The inode object Stores general information about a specific file.[存在磁盘上]
*For disk-based filesystems, this object usually corresponds to a file control block stored on disk.
*Each inode object is associated with an inode number, which uniquely identifies the file within the filesystem.
*
/
crash> inode
struct inode {
    umode_t i_mode;
    unsigned short i_opflags;
    uid_t i_uid;
    gid_t i_gid;
    unsigned int i_flags;
    const struct inode_operations *i_op;
    struct super_block *i_sb;
    struct address_space *i_mapping;
    unsigned long i_ino;
    union {
        const unsigned int i_nlink;
        unsigned int __i_nlink;
    };
    dev_t i_rdev;
    struct timespec i_atime;
    struct timespec i_mtime;
    struct timespec i_ctime;
    spinlock_t i_lock;
    unsigned short i_bytes;
    blkcnt_t i_blocks;
    loff_t i_size;
    seqcount_t i_size_seqcount;
    unsigned long i_state;
    struct mutex i_mutex;
    unsigned long dirtied_when;
    struct hlist_node i_hash;
    struct list_head i_wb_list;
    struct list_head i_lru;
    struct list_head i_sb_list;
    union {
        struct list_head i_dentry;
        struct rcu_head i_rcu;
    };
    atomic_t i_count;
    unsigned int i_blkbits;
    u64 i_version;
    atomic_t i_dio_count;
    atomic_t i_writecount;
    const struct file_operations *i_fop;
    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;
    __u32 i_fsnotify_mask;
    struct hlist_head i_fsnotify_marks;
    void *i_private;
}
SIZE: 344


/*The dentry object
*Stores information about the linking of a directory entry (that is, a particular name of the file)
*with the corresponding file. Each disk-based filesystem stores this information in its own
*particular way on disk.【存在磁盘上】
* mount_pseudo -> __d_alloc ->生成新的dentry.
*
/
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 list_head d_alias;    /* inode alias list */
};
/*************************************************************************************/
 file 又是怎样和上面的数据结构发生关系的那?

/*The file object
Stores information about the interaction between an open file and a process. This information
exists only in kernel memory during the period when a process has the file open.
*/
crash> file
struct file {
    union {
        struct list_head fu_list;
        struct rcu_head fu_rcuhead;
    } f_u;
    struct path f_path;
    const struct file_operations *f_op;
    spinlock_t f_lock;
    int f_sb_list_cpu;
    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;
    void *private_data;
    struct list_head f_ep_links;
    struct list_head f_tfile_llink;
    struct address_space *f_mapping;
}
SIZE: 152

crash> file_operations
struct file_operations {
    struct module *owner;
    loff_t (*llseek)(struct file *, loff_t, int);
    ssize_t (*read)(struct file *, char *, size_t, loff_t *);
    ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
    ssize_t (*aio_read)(struct kiocb *, const struct iovec *, unsigned long, loff_t);
    ssize_t (*aio_write)(struct kiocb *, const struct iovec *, unsigned long, loff_t);
    int (*readdir)(struct file *, void *, filldir_t);
    unsigned int (*poll)(struct file *, struct poll_table_struct *);
    long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
    long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
    int (*mmap)(struct file *, struct vm_area_struct *);
    int (*open)(struct inode *, struct file *);
    int (*flush)(struct file *, fl_owner_t);
    int (*release)(struct inode *, struct file *);
    int (*fsync)(struct file *, loff_t, loff_t, int);
    int (*aio_fsync)(struct kiocb *, int);
    int (*fasync)(int, struct file *, int);
    int (*lock)(struct file *, int, struct file_lock *);
    ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);
    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*check_flags)(int);
    int (*flock)(struct file *, int, struct file_lock *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **);
    long (*fallocate)(struct file *, int, loff_t, loff_t);
}
SIZE: 104

原创粉丝点击