Linux文件系统(二)—— 文件读写
2021/12/1 7:07:35
本文主要是介绍Linux文件系统(二)—— 文件读写,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
【前言】
文件系统是结合了众多工程师智慧的结晶,所以在这个过程中,会出现各种各样的小技术手段来解决一些实际性问题,从而产生了很多技术词汇。
【文件系统Overview】
Linux一切皆文件:普通文件、目录文件(也就是文件夹)、设备文件、链接文件、管道文件、套接字文件(数据通信的接口)等等。引入文件系统,帮助我们屏蔽底层实现的细节(不必care扇区,cache,文件管理),我们只需通过VFS提供的fs_op就可以对文件进行对应的操作。
Android 支持的文件系统: ext4 vfat f2fs sdcardfs fuse(fuse解决了文件系统必须在内核态的难题。将文件系统的实现从内核态搬到了用户态)
Android linux 文件系统核心: VFS(1.向上提供接口,向下兼容文件系统,实现了inode/page cache等公共部分,让其他文件系统无需重复实现)
【文件系统四大对象】
1. 超级块super_block:
struct super_block { struct list_head s_list; /* Keep this first 指向超级块链表的指针*/ dev_t s_dev; /*具体文件系统的块设备描述符*/ 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; /*指向super_block操作的函数集合*/ alloc_inode () /*创建并初始化一个inode*/ write_inode() /*将inode同步到磁盘*/ sync_fs() /*同步文件系统元数据到磁盘*/ list_head s_inodes; /* all inodes */ list_head s_inodess_dirty; /* dirty inodes */ void *s_fs_info; /* Filesystem private info 具体文件系统的私有数据*/ *** }
- 超级块用来描述整个文件系统的信息
- 每个具体的文件系统都有自己的超级块
- VFS超级块是各种文件系统在安装时建立的,并在卸载时被自动删除,其数据结构是super_block
- 所有超级块对象都以双向循环链表的形式链接在一起
1.1 struct super_operations:超级块操作表
2. inode:index node
struct inode { struct hlist_node i_hash; /* 哈希表 */ struct list_head i_list; /* 索引节点链表 */ struct list_head i_dentry; /* 目录项链表 */ unsigned long i_ino; /* 节点号 */ atomic_t i_count; /* 引用记数 */ umode_t i_mode; /* 访问权限控制 */ unsigned int i_nlink; /* 硬链接数 */ uid_t i_uid; /* 使用者id */ gid_t i_gid; /* 使用者id组 */ kdev_t i_rdev; /* 实设备标识符 */ loff_t i_size; /* 以字节为单位的文件大小 */ struct timespec i_atime; /* 最后访问时间 */ struct timespec i_mtime; /* 最后修改(modify)时间 */ struct timespec i_ctime; /* 最后改变(change)时间 */ unsigned int i_blkbits; /* 以位为单位的块大小 */ unsigned long i_blksize; /* 以字节为单位的块大小 */ unsigned long i_version; /* 版本号 */ unsigned long i_blocks; /* 文件的块数 */ unsigned short i_bytes; /* 使用的字节数 */ spinlock_t i_lock; /* 自旋锁 */ struct rw_semaphore i_alloc_sem; /* 索引节点信号量 */ struct inode_operations *i_op; /* 索引节点操作表 */ struct file_operations *i_fop; /* 默认的索引节点操作 */ struct super_block *i_sb; /* 相关的超级块 */ struct file_lock *i_flock; /* 文件锁链表 */ struct address_space *i_mapping; /* 相关的地址映射 */ struct address_space i_data; /* 设备地址映射 */ struct dquot *i_dquot[MAXQUOTAS]; /* 节点的磁盘限额 */ struct list_head i_devices; /* 块设备链表 */ struct pipe_inode_info *i_pipe; /* 管道信息 */ struct block_device *i_bdev; /* 块设备驱动 */ unsigned long i_dnotify_mask; /* 目录通知掩码 */ struct dnotify_struct *i_dnotify; /* 目录通知 */ unsigned long i_state; /* 状态标志 */ unsigned long dirtied_when; /* 首次修改时间 */ unsigned int i_flags; /* 文件系统标志 */ unsigned char i_sock; /* 可能是个套接字吧 */ atomic_t i_writecount; /* 写者记数 */ void *i_security; /* 安全模块 */ __u32 i_generation; /* 索引节点版本号 */ union { void *generic_ip; /* 文件特殊信息 */ } u;
- 文件系统处理文件所需要的所有信息都保存在称为索引节点的inode结构体中
- 同一个文件系统中,每个文件的索引节点号都是唯一的
- 与索引节点关联的方法由struct inode_operations来描述
- inode有两个设备号:i_dev(常规文件的设备号),i_rdev(某一设备的设备号)
- LInux文件系统的另外一大特色:设备即文件 —— 驱动中设备号的来源。
2.1 struct inode_operations:index node操作函数
3. dentry:目录项
struct dentry { atomic_t d_count; //目录项对象使用计数器,可以有未使用态,使用态和负状态 unsigned int d_flags; //目录项标志 struct inode *d_inode; //与文件名关联的索引节点 struct dentry *d_parent; //父目录的目录项对象 struct list_head d_hash; //散列表表项的指针 struct list_head d_lru; //未使用链表的指针 struct list_head d_child; //父目录中目录项对象的链表的指针 struct list_head d_subdirs; //对目录而言,表示子目录目录项对象的链表 struct list_head d_alias; //相关索引节点(别名)的链表 int d_mounted; //对于安装点而言,表示被安装文件系统根项 struct qstr d_name; //文件名 unsigned long d_time; /* used by d_revalidate */ struct dentry_operations *d_op; //目录项方法 struct super_block *d_sb; //文件的超级块对象 vunsigned long d_vfs_flags; void *d_fsdata; //与文件系统相关的数据 unsigned char d_iname [DNAME_INLINE_LEN]; //存放短文件名 };
- 存在于内存的目录项缓存,为了提高查找性能而设计,动态生成的(哈希表,或组织为一颗树,链表)。
- 每个文件除了一个struct inode结构体外,还要一个目录项struct dentry结构,通过其d_hash域链入哈希表中
- 不管是文件夹还是文件(目录),都属于目录项,所有的目录项在一起构成一颗庞大的目录树。
- dentry对象有三种状态:被使用,未被使用和负状态。
3.1 struct dentry_operations
(未完待续)
PS:
【I/O 缓冲区】
Cache:解决的是速度不同步的问题。
- Buffer : 用于内存和硬盘的缓冲,缓冲“写”操作,保存即将要写入到磁盘上的数据。
- Cache:一般指高速缓存,用于CPU和内存之间的缓冲,解决读的问题,保存从磁盘上读出的数据。
Buffer Cache和 Page Cache
- buffer cache:块缓冲器,面向块设备(文件系统的块)。
- page cache: 页缓冲器,面向虚拟内存。已映射到内存的某些物理设备(例如磁盘)上的数据,包含来自最近访问的“文件”的整个页面。在页面I / O操作(例如read()])中,内核检查数据是否驻留在page cache中。如果数据在page cache中,则内核可以快速返回请求的页面,而不必从磁盘读取数据。
这篇关于Linux文件系统(二)—— 文件读写的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法