[文件系统]文件系统学习笔记(四)---常用数据结构

1,基本数据结构
file_system_type
 每种文件系统对应一个文件系统类型结构,注册之后形成单链表,链表表头为file_systems(全局变量).
Superblock
 反应文件系统整体的控制信息,超级块以多种方式存在。(磁盘超级快、内存超级块、VFS超级块)
Inode
 反应了某个文件系统对象的一般元信息(metadata)。(磁盘inode、内存inode、VFS inode)
Dentry
 反应了某个文件系统对象在文件系统树中的位置。
mount
 反映了一个已装载文件系统实例。

2,文件系统的注册
 在register_filesystem()函数中来向内核注册文件系统,所有的文件系统都在一个单链表中,各个文件系统的名称存储为字符串,用于描述文件系统结构为file_system_type,内核中用一个名为file_systems 的全局变量来指向该链表的表头。

[cpp] view plaincopy

  1. struct file_system_type {
  2. const char *name;  //保存了文件系统的名称,是一个字符串
  3. int fs_flags;
  4. struct super_block *(*get_sb) (struct file_system_type *, int,)//读超级块的方法,在文件系统装载时调用;在kern_mount函数中调用,用于取
  5. 得本文件系统(分区)的super_block,并将之填充到struct vfsmount的mnt_sb成员中。
  6. const char *, void *, struct vfsmount *);
  7. void (*kill_sb) (struct super_block *);//删除超级块的方法
  8. struct module *owner;
  9. struct file_system_type * next;
  10. struct list_head fs_supers;//相同类型文件系统的超级块对象双向链表头;每个文件系统都有一个超级块,但有些文件系统可能被安装在不同的设备上,而每个具体的设备都有一个超级块,这些形成一个链表
  11. };

在一个系统上,比如smartphone平台,有很多分区,比如/data和/system分区都是ext4文件系统,但是系统中还是只有一个file_system_type的成员,不过每个分区对应的ext4文件系统对应不同的super_block,fs_supers就是将这些相同文件系统不同的super block链接起来形成双向循环链表,fs_supers是链表头,链表元素由super_block结构体的s_instance成员表示。系统中所有的super_block由super_block结构体的s_list链接成双向循环链表,表头是super_blocks变量表示。

3,文件系统的装载和卸载
 使用mount命令可以查询目录树中各种文件系统的装载情况, 在将文件系统装载到一个目录时,装载点的内容被替换为即将装载的文件系统的相对根目录的内容,前一个目录数据消失,直到新文件系统卸载的时候才重新出现。

[cpp] view plaincopy

  1. struct vfsmount {
  2. struct list_head mnt_hash;
  3. struct vfsmount *mnt_parent; /* fs we are mounted on */
  4. struct dentry *mnt_mountpoint; /* dentry of mountpoint */
  5. struct dentry *mnt_root; /* root of the mounted tree */
  6. struct super_block *mnt_sb; /* pointer to superblock */
  7. struct list_head mnt_mounts; /* list of children, anchored here */
  8. struct list_head mnt_child; /* and going through their mnt_child */
  9. int mnt_flags;
  10. char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
  11. struct list_head mnt_list;
  12. struct list_head mnt_expire; /* link in fs-specific expiry list */
  13. struct list_head mnt_share; /* circular list of shared mounts */
  14. struct list_head mnt_slave_list;/* list of slave mounts */
  15. struct list_head mnt_slave; /* slave list entry */
  16. struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
  17. struct mnt_namespace *mnt_ns; /* containing namespace */
  18. atomic_t mnt_count;
  19. int mnt_expiry_mark; /* true if marked for expiry */
  20. };

vfsmount成员mnt_mountpoint表示的是装载点在父文件系统中的dentry,文件系统本身的相对根目录所对应的dentry保存在mnt_root中,两个dentry实例表示同一目录,这意味着在文件系统卸载后不必删除此前的装载点信息。

在新版本的linux内核中,使用了struct mount结构体代替了struct vfsmount结构体。
在装载新的文件系统时,vfsmount并不是唯一需要在内存中创建的结构,装载操作开始于超级块的读取,超级块是整个文件系统的元数据的容器。基于磁盘的文件系统,超级块(磁盘上的)是保存在磁盘设备上固定位置的一个或多个块,在装载该磁盘上的文件系统时,磁盘上的超级块被读入内存,并根据它构造内存中的超级块。

[cpp] view plaincopy

  1. struct super_block {
  2. struct list_head s_list; /* 链表元素,表头super_blokcs,标示所有的超级块链表,指向链表相邻元素指针,
  3. dev_t s_dev; /* 存储超级块信息的块设备
  4. unsigned long s_blocksize;
  5. unsigned char s_blocksize_bits;  //文件系统的块长度,以位的形式标示
  6. unsigned char s_dirt;  //超级块是否写脏,需要回写到磁盘
  7. unsigned long long s_maxbytes; /* 支持的文件的最大长度,默认是231-1
  8. struct file_system_type *s_type; //指向file_system_type类型的指针
  9. struct super_operations *s_op;
  10. unsigned long s_flags; //s_flags 这个标志为设置为1或者0,用以表示整个设备上的文件是否允许使用强制锁。
  11. unsigned long s_magic;
  12. struct dentry *s_root; //指向文件系统根目录的dentry对象
  13. struct xattr_handler **s_xattr;
  14. struct list_head s_inodes; /* 文件系统的所有inode链表的表头
  15. struct list_head s_dirty; /* 指向所有dirty的inode对象 */
  16. struct list_head s_io; /* parked for writeback */
  17. struct list_head s_more_io; /* parked for more writeback */
  18. struct list_head s_files; //表头,所有打开的文件
  19. struct block_device *s_bdev;  //对于磁盘文件系统,指向块设备描述符的指针,否则为空
  20. struct list_head s_instances;  //链表元素,表头file_system_type->fs_supers,标示同一个文件系统的多次装载链表
  21. char s_id[32]; /* 具体设备名,比如为/dev/block/mmcblkop1 */
  22. void *s_fs_info; /* 指向具体文件系统的super block结构,比如fat32对应的结构体是msdos_sb_info结构体*/
  23. u32 s_time_gran;
  24. };

超级快可以管理系统中inode节点的原因是文件系统内所有的inode要链接到超级快的链表头。

所有超级快对象都以双向循环链表的形式连接在一起,链表第一个元素用super_blocks变量表示,sb_lock自旋锁保护链表免受多处理器系统上的同时访问。s_fs_info指向属于具体文件系统的超级快信息,例如具体文件系统是EXT2,则s_fs_info指向ext2_sb_info,s_dirty表示的修改脏标记,表示内存中的超级快信息是否和硬盘上超级快信息同步,
 对于每个转载的文件系统而言,都有且只有一个超级快实例

 

[cpp] view plaincopy

    1. struct inode {
    2. struct hlist_node i_hash;  //用于散列链表指针
    3. struct list_head i_list;   //描述索引节点当前状态链表指针
    4. struct list_head i_sb_list;  //用于超级快的索引节点链表的指针
    5. struct list_head i_dentry;  //引用索引节点的目录项对象链表的头
    6. unsigned long i_ino;  //索引节点号
    7. atomic_t i_count;  //引用计数器
    8. unsigned int i_nlink;  //硬链接数目
    9. uid_t i_uid;  //所有者标识符
    10. gid_t i_gid;  //组标识符
    11. dev_t i_rdev;  //实设备标识符
    12. unsigned long i_version;
    13. loff_t i_size;  //文件字节数目
    14. struct timespec i_atime;  //上次访问时间
    15. struct timespec i_mtime;  //上次写文件时间
    16. struct timespec i_ctime; //上次修改索引节点时间
    17. unsigned int i_blkbits; //块的位数
    18. blkcnt_t i_blocks;  //文件的块数
    19. umode_t i_mode; //文件类型与访问权限
    20. struct inode_operations *i_op; //索引节点的操作
    21. const struct file_operations *i_fop; //缺省文件操作
    22. struct super_block *i_sb;  //指向超级快对象的指针
    23. struct address_space *i_mapping; //指向address_space对象的指针
    24. struct address_space i_data; //文件的address_space对象
    25. struct dquot *i_dquot[MAXQUOTAS];  //索引节点的磁盘限额
    26. struct list_head i_devices;  //用于具体的字符或者快设备的所以节点链表指针
    27. union {
    28. struct pipe_inode_info *i_pipe;
    29. struct block_device *i_bdev;
    30. struct cdev *i_cdev;
    31. };
    32. int i_cindex;  //拥有一组次设备号的设备文件的索引
    33. __u32 i_generation;
    34. unsigned long i_state;  //索引节点状态标识
    35. unsigned long dirtied_when; /* jiffies of first dirtying */
    36. unsigned int i_flags;  //文件系统安装标志,比如为MS_MANDLOCK可以有选择的对一个文件是否使用强制锁。
    37. atomic_t i_writecount;  //用于写进程的引用计数
    38. void *i_security;  //指向索引节点安全结构指针
    39. };
时间: 2024-11-06 21:42:59

[文件系统]文件系统学习笔记(四)---常用数据结构的相关文章

Java学习笔记-5.常用数据结构

一.数组 1.Java是将数组作为对象来实现的,而非连续的存储空间 2.在Java中,数组时一个类,提供了一些方法和属性,如数组长度array.length 3.Java中数组名可视为对象引用,在初始化时,不能直接定义长度 例:int a[3];    //错误的声明方法 4.数组中的元素也可以是复合数据类型的,这时数组元素实际上是对象引用 例: Complex[] arr = new Complex[3]; int i; for(i = 0; i < arr.length; i++) { ar

小猪的数据结构学习笔记(四)

小猪的数据结构学习笔记(四) 线性表之静态链表 --转载请注明出处:coder-pig 本章引言: 在二,三中中我们分别学习了顺序表中的线性表与单链表,线性表有点类似于 我们前面所学的数组,而单链表使用的最多的是指针,这里问个简单的问题, 如果是在以前没有指针的话,前辈先人们怎么实现单链表呢?大家思考下! 没有指针,那么用什么来代替呢?前辈先人们非常机智,想出了使用下标+游标的方式 来实现单链表的效果!也就是今天要讲的--静态链表! 当然你也可以直接跳过本章,因为有了单链表就没有必要用静态链表了

NLTK学习笔记(四):自然语言处理的一些算法研究

自然语言处理中算法设计有两大部分:分而治之 和 转化 思想.一个是将大问题简化为小问题,另一个是将问题抽象化,向向已知转化.前者的例子:归并排序:后者的例子:判断相邻元素是否相同(与排序). 这次总结的自然语言中常用的一些基本算法,算是入个门了. 递归 使用递归速度上会受影响,但是便于理解算法深层嵌套对象.而一些函数式编程语言会将尾递归优化为迭代. 如果要计算n个词有多少种组合方式?按照阶乘定义:n! = n*(n-1)*...*1 def func(wordlist): length = le

python 学习笔记 13 -- 常用的时间模块之time

Python 没有包含对应日期和时间的内置类型,不过提供了3个相应的模块,可以采用多种表示管理日期和时间值: *    time 模块由底层C库提供与时间相关的函数.它包含一些函数用于获取时钟时间和处理器的运行时间,还提供了基本解析和字符串格式化工具 *    datetime 模块为日期.时间以及日期时间值提供一个更高层接口.datetime 中的类支持算术.比较和时区配置. *    calendar 模块可以创建周.月和年的格式化表示.它还可以用来计算重复事件.给定日期是星期几,以及其他基

Linux System Programming 学习笔记(四) 高级I/O

1. Scatter/Gather I/O a single system call  to  read or write data between single data stream and multiple buffers This type of I/O is so named because the data is scattered into or gathered from the given vector of buffers Scatter/Gather I/O 相比于 C标准

Caliburn.Micro学习笔记(四)----IHandle&lt;T&gt;实现多语言功能

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路 先看一下效果 点击英文  变成英文状态点chinese就会变成中文                          源码的下载地址在文章的最下边 多语言用的是资源文件建

代码管理工具 --- git的学习笔记四《重新整理git(1)》

1.创建版本库 mkdir  创建目录 cd  地址,到该地址下 pwd 显示当前目录 1.创建目录 $ mkdir startGit $ cd startGit $ pwd 显示当前目录 或者cd到桌面,然后再创建目录 2.初始化版本库 $ git init 初始化仓库 提示信息:Initialized empty Git repository in /Users/xingzai/Desktop/startGit/.git/ 建立一个空的git仓库在/Users/xingzai/Desktop

Linux学习笔记四:Linux的文件搜索命令

1.文件搜索命令  which 语法:which [命令名称] 范例:$which ls  列出ls命令所在目录 [[email protected] ~]$ which ls alias ls='ls --color=auto' /bin/ls 另外一个命令:whereis [名称名称],也可以列出命令所在目录. [[email protected] ~]$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/ma

python 学习笔记 14 -- 常用的时间模块之datetime

书接上文,前面我们讲到<常用的时间模块之time>,这次我们学习datetime -- 日期和时间值管理模块 使用apihelper 查看datetime 模块,我们可以看到简单的几项: date       ---  日期对象,结构为date(year, month, day) time       ---  时间值对象,结构为 time([hour[, minute[, second[, microsecond[, tzinfo]]]]]).时间对象所有的参数都是可选的.tzinfo 可以

Swift学习笔记四:数组和字典

最近一个月都在专心做unity3d的斗地主游戏,从早到晚,最后总算是搞出来了,其中的心酸只有自己知道.最近才有功夫闲下来,还是学习学习之前的老本行--asp.net,现在用.net做项目流行MVC,而不是之前的三层,既然技术在更新,只能不断学习,以适应新的技术潮流! 创建MVC工程 1.打开Visual studio2012,新建MVC4工程 2.选择工程属性,创建MVC工程 3.生成工程的目录 App_Start:启动文件的配置信息,包括很重要的RouteConfig路由注册信息 Conten