天天看点

linux文件系统(一) - 概述

  1. ​​linux文件系统(一) - 概述​​
  2. ​​linux文件系统(二) - 虚拟文件系统​​
  3. ​​linux文件系统(三) - 内核回写机制​​
  4. ​​Linux文件系统(四) - 从文件系统到块设备/从page cache到bio, request, request_queue​​
  5. linux文件系统(五) - I/O调度算法
  6. ​​linux文件系统(六) - 块设备驱动​​

文件系统架构

结构体

虚拟文件系统提供的struct super_operations, struct inode_operations, struct file_operations由具体的文件系统实现结构体中对应的接口。

struct super_block

struct super_operations

struct super_operations {
        struct inode *(*alloc_inode)(struct super_block *sb);
        void (*destroy_inode)(struct inode *);
        void (*dirty_inode) (struct inode *, int flags);
        int (*write_inode) (struct inode *, struct writeback_control *wbc);
        int (*drop_inode) (struct inode *);
        void (*evict_inode) (struct inode *);
        void (*put_super) (struct super_block *);
        int (*sync_fs)(struct super_block *sb, int wait);
        int (*freeze_fs) (struct super_block *);
        int (*unfreeze_fs) (struct super_block *);
        int (*statfs) (struct dentry *, struct kstatfs *);
        int (*remount_fs) (struct super_block *, int *, char *);
        void (*umount_begin) (struct super_block *);

        int (*show_options)(struct seq_file *, struct dentry *);
        int (*show_devname)(struct seq_file *, struct dentry *);
        int (*show_path)(struct seq_file *, struct dentry *);
        int (*show_stats)(struct seq_file *, struct dentry *);
        int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
        int (*nr_cached_objects)(struct super_block *);
        void (*free_cached_objects)(struct super_block *, int);
};      

struct inode

struct inode_operations

struct inode_operations {
        struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
        void * (*follow_link) (struct dentry *, struct nameidata *);
        int (*permission) (struct inode *, int);
        struct posix_acl * (*get_acl)(struct inode *, int);

        int (*readlink) (struct dentry *, char __user *,int);
        void (*put_link) (struct dentry *, struct nameidata *, void *);

        int (*create) (struct inode *,struct dentry *, umode_t, bool);
        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 *,umode_t);
        int (*rmdir) (struct inode *,struct dentry *);
        int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
        int (*rename) (struct inode *, struct dentry *,
                        struct inode *, struct dentry *);
        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 *);
        int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
                      u64 len);
        int (*update_time)(struct inode *, struct timespec *, int);
        int (*atomic_open)(struct inode *, struct dentry *,
                           struct file *, unsigned open_flag,
                           umode_t create_mode, int *opened);
} ____cacheline_aligned;      

struct file

struct file_operations

struct file_operations {
        struct module *owner;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char __user *, 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 id);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, loff_t, loff_t, int datasync);
        int (*aio_fsync) (struct kiocb *, int datasync);
        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 *file, int mode, loff_t offset,
                          loff_t len);
        int (*show_fdinfo)(struct seq_file *m, struct file *f);
};      

注册文件系统

static struct file_system_type vfat_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "vfat",
        .mount          = vfat_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
}
static int __init init_vfat_fs(void) 
{
    return register_filesystem(&vfat_fs_type);
}
module_init(init_vfat_fs)      

register_filesystem在fs/filesystem.c文件中实现,主要是在全局struct file_system_type *file_systems链表中查找是否已存在文件系统,如果不存在,那么将当前的文件系统添加到全局file_systems链表中

注册super_operations\inode_operations\file_operations

在struct file_system_type结构体中的mount对应的函数是vfat_mount

vfat_mount
    mount_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
vfat_fill_super
    fat_fill_super(sb, data, silent, 1, setup);
        sb->s_op = &fat_sops;//struct super_operations,位于inode.c
        setup
            //struct inode_operations, 位于namei_vfat.c
            MSDOS_SB(sb)->dir_ops = &vfat_dir_inode_operations;      

在fat_fill_super函数中会赋值struct super_operations,然后通过setup函数赋值struct inode_operations,

//fs/fat/namei_vfat.c
static const struct inode_operations vfat_dir_inode_operations = {
        .create         = vfat_create,
        .lookup         = vfat_lookup,
        .unlink         = vfat_unlink,
        .mkdir          = vfat_mkdir,
        .rmdir          = vfat_rmdir,
        .rename         = vfat_rename,
        .setattr        = fat_setattr,
        .getattr        = fat_getattr,
};
vfat_mkdir
    fat_build_inode
        fat_fill_inode
            if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
                inode->i_op = sbi->dir_ops;
                inode->i_fop = &fat_dir_operations;
            } else { /* not a directory */
                inode->i_op = &fat_file_inode_operations;
                inode->i_fop = &fat_file_operations;
            }