Linux文件系统三(无持久存储文件系统和mount)

本文详细介绍了Linux中无持久存储文件系统,特别是proc文件系统的概念和作用,以及文件系统的数据结构,如proc_dir_entry、inode等。接着,文章深入探讨了mount流程,包括初始化、mount系统调用、mount调用流程的关键步骤,如do_new_mount、lock_mount和graft_tree等。最后,简要提到了掩码的概念。整个内容旨在帮助读者理解Linux内核中的文件系统管理和挂载机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创作人QQ:851301776,邮箱:[email protected]
        欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点!

个人座右铭:
         1.没有横空出世,只要厚积一定发。
         2.你可以学历不高,你可以不上学,但你不能不学习
 

一、无持久存储文件系统介绍

        proc文件系统(proc filesystem),它使得内核可以生成与系统状态和配置有关的信息,该信息可以由用户和系统程序从普通文件读取,而无需专门的工具与内核通信。在某些情况下,一个简单的cat命令就足够了。数据不仅可以从内核读取,还可以通过向proc文件系统的文件写入字符串,来向内核发送数据echo "value" > proc/file, sysfs是另一个特别重要的虚拟文件系统,它的目的是为了从内核向用户层导出非常结构化的信息。与procfs相比,并不提供用户直接使用,因为信息是层次化,深度嵌套的。

        proc文件系统本身是内核提供给用户优化内核参数的方法,还有其他作用的小文件系统,比如debugfs,libfs。

二、数据结构

1.代码结构

 2.proc_dir_entry

struct proc_dir_entry { 
    unsigned int low_ino; 
    unsigned short namelen; //指定文件名的长度 
    const char *name; //存储文件名的字符串指针 
    mode_t mode; 
    nlinkt_t nlink; //指定了目录中子目录和符号链接的数量 
    uid_t uid; 
    gid_t gid; 
    loff_t size; 
    struct inode_operations *proc_iops; 
    const struct file_operations *proc_fops; 
    get_info_t *get_info; //指向相关子系统中返回所需数据的例程 
    struct module *owner; 
    struct proc_dir_entry *next, *parent, *subdir; // 平级目录,上一级目录,下一级目录 
    void *data; 
    read_proc_t *read_proc; //从内核读取数据 
    write_proc_t *write_proc; //从内核写入数据 
}

read_proc与write_proc是两个函数指针 <proc_fs.h>

typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data); 
typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data);

3.proc_inode

union proc_op { 
    int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); 
    int (*proc_read)(struct task_struct *task, char *page); 
};

struct proc_inode { 
    struct pid *pid; 
    int fd; 
    union proc_op op; 
    struct proc_dir_entry *pde; 
    struct inod vfs_inode; 
}

        该数据结构用来将proc的数据与vfs层的inode数据关联起来。pde指向关联到proc数据项的

proc_dir_entry实例。

4.file_system_type

struct file_system_type { 
    const char *name; 
    int fs_flags; 
#define FS_REQUIRES_DEV 1 
#define FS_BINARY_MOUNTDATA 2 
#define FS_HAS_SUBTYPE 4 
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ 
#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */ 
#define FS_USERNS_VISIBLE 32 /* FS must already be visible */ 
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ 
    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 s_writers_key[SB_FREEZE_LEVELS]; 
    struct lock_class_key i_lock_key; 
    struct lock_class_key i_mutex_key; 
    struct lock_class_key i_mutex_dir_key; 
};

5.super_block

struct super_block { 
    struct list_head s_list; /* Keep this first */ 
    dev_t s_dev; /* search index; _not_ kdev_t */ 
    unsigned char s_blocksize_bits; 
    unsigned long s_blocksize; 
    loff_t s_maxbytes; /* Max file size */ 
    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_iflags; /* internal SB_I_* flags */ 
    unsigned long s_magic; 
    struct dentry *s_root; 
    struct rw_semaphore s_umount; 
    int s_count; atomic_t s_active; 
#ifdef CONFIG_SECURITY 
    void *s_security; 
#endif
    const struct xattr_handler **s_xattr; 
    struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */ 
    struct list_head s_mounts; /* list of mounts; _not_ for fs use */ 
    struct block_device *s_bdev; 
    struct backing_dev_info *s_bdi; 
    struct mtd_info *s_mtd; 
    struct hlist_node s_instances; 
    unsigned int s_quota_types; /* Bitmask of supported quota types */ 
    struct quota_info s_dquot; /* Diskquota specific options */ 
    struct sb_writers s_writers; 
    char s_id[32]; /* Informational name */ 
    u8 s_uuid[16]; /* UUID */ 
    void *s_fs_info; /* Filesystem private info */ 
    unsigned int s_max_links; 
    fmode_t s_mode; /* Granularity of c/m/atime in ns. Cannot be worse than a second */ 
    u32 s_time_gran; /** The next field is for VFS *only*. No filesystems have any business * even looking at it. You had been warned. */ 
    struct mutex s_vfs_rename_mutex; /* Kludge */ /*
* Filesystem subtype. If non-empty the filesystem type field * in /proc/mounts will be "type.subtype" */ 
    char *s_subtype; /** Saved mount options for lazy filesystems using * generic_show_options() */ 
    char __rcu *s_options; 
    const struct dentry_operations *s_d_op; /* default d_op for dentries */ 
    /** Saved pool identifier for cleancache (-1 means none) */ 
    int cleancache_poolid; 
    struct shrinker s_shrink; /* per-sb shrinker handle */ 
    /* Number of inodes with nlink == 0 but still referenced */ 
    atomic_long_t s_remove_count; /* Being remounted read-only */ 
    int s_readonly_remount; /* AIO completions deferred from interrupt context */                  struct workqueue_struct *s_dio_done_wq; struct hlist_head s_pins; /** Keep the lru lists last in the structure so they always sit on their * own individual cachelines. */ struct list_lru s_dentry_lru ____cacheline_aligned_in_smp; struct list_lru s_inode_lru ____cacheline_aligned_in_smp; struct rcu_head rcu; struct work_struct destroy_work; struct mutex s_sync_lock; /* sync serialisation lock */ /** Indicates how deep in a filesystem stack this SB is */ int s_stack_depth; /* s_inode_list_lock protects s_inodes */ spinlock_t s_inode_list_lock ____cacheline_aligned_in_smp; struct list_head s_inodes; /* all inodes */ };

6.索引节点(inode)

struct inode { 
    umode_t i_mode; 
    unsigned short i_opflags;
    kuid_t i_uid; 
    kgid_t i_gid; 
    unsigned int i_flags; 
#ifdef CONFIG_FS_POSIX_ACL 
    struct posix_acl *i_acl; 
    struct posix_acl *i_default_acl; 
#endif
    const struct inode_operations *i_op; 
    struct super_block *i_sb; 
    struct address_space *i_mapping; 
#ifdef CONFIG_SECURITY 
    void *i_security; 
#endif/* 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; 
#ifdef __NEED_I_SIZE_ORDERED 
    seqcount_t i_size_seqcount; #endif/* Misc */ 
    unsigned long i_state; 
    struct mutex i_mutex; 
    unsigned long dirtied_when; /* jiffies of first dirtying */ 
    unsigned long dirtied_time_when; 
    struct hlist_node i_hash; 
    struct list_head i_io_list; /* backing dev IO list */ 
#ifdef CONFIG_CGROUP_WRITEBACK 
    struct bdi_writeback *i_wb; /* the associated cgroup wb */ 
    /* foreign inode detection, see wbc_detach_inode() */ 
    int i_wb_frn_winner;
    u16 i_wb_frn_avg_time; 
    u16 i_wb_frn_history; 
#endif
    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; 
    atomic64_t i_sequence; /* see futex */ 
    atomic_t i_count; 
    atomic_t i_dio_count; 
    atomic_t i_writecount; 
#ifdef CONFIG_IMA 
    atomic_t i_readcount; /* struct files open RO */ 
#endif
    const struct file_operations *i_fop; /* former ->i_op- >default_file_ops */
    struct file_lock_context *i_flctx; 
    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; char *i_link; 
    };
    __u32 i_generation; 
#ifdef CONFIG_FSNOTIFY 
    __u32 i_fsnotify_mask; /* all events this inode cares about */ 
    struct hlist_head i_fsnotify_marks; 
#endif
    void *i_private; /* fs or device private pointer */ 
}; 

7.目录项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 */ 
    struct lockref d_lockref; /* per-dentry lock and refcount */ 
    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 */ 
    struct list_head d_child; /* child of parent list */ 
    struct list_head d_subdirs; /* our children */ 
    /** d_alias and d_rcu can share memory */ 
    union { 
        struct hlist_node d_alias; /* inode alias list */ 
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QQ851301776

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值