文件系统概念:
文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易,文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。在写入新数据之前,用户不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成,用户只需要记住数据被写入到了哪个文件中。
· 文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)。
文件系统是一种用于向用户提供底层数据访问的机制。它将设备中的空间划分为特定大小的块(扇区),一般每块512字节。数据存储在这些块中,大小被修正为占用整数个块。由文件系统软件来负责将这些块组织为文件和目录(即用户可以直接通过文件路径和文件名来访问磁盘数据,而不需要知道数据存储的扇区位置等信息),并记录哪些块被分配给了哪个文件,以及哪些块没有被使用。
linux虚拟文件(VFS)系统
VFS可以理解为 虚拟文件系统virtual filesystem 也可以理解为 虚拟文件系统转换virtual filesystem switch,是一个内核软件层,用来处理与unix标准文件系统相关的所有系统调用。其主要作用是为各种文件系统提供了统一接口。例如:使用同一个read函数可以读取U盘数据(FAT),也可以读取硬盘数据(Ext2),以及光盘数据(CD-ROM)。
VFS支持的文件系统主要分为三类
磁盘文件系统:这些文件系统管理在本地磁盘分区中可用的存储空间或者其他可以起到磁盘作用的设备(如U盘)。Ext2/3 System V,MINIX,MS-DOS,VFAT,NTFS,CD-ROM等。
网络文件系统:这些文件可以轻易访问属于其他网络计算机的文件系统所包含的文件。虚拟文件系统所支持的一些网络文件系统有:NFS, Coda, NCP
特殊文件系统:这些文件系统不管理本地或远程磁盘空间。例如基于内存的/proc文件系统。
通用文件系统模型
在通用文件系统中目录被看做文件,每个文件操作都是通过指针实现,不同的文件系统所使用的操作指针不同。
通用系统模型由下列对象类型组成(主要数据结构):
超级块结构(struct super_block {…} ) 超级块对象
该结构保存了一个被安装在linux系统上的文件系统的信息。对于基于磁盘的文件系统,该结构一般和保存在磁盘上的”文件系统控制块”对应。也就是说如果是磁盘文件系统,该结构保存的磁盘文件系统的控制信息。
inode结构( struct inode {…} ) 索引节点对象
该结构中存储的是一个具体文件的一般信息,对于一个基于磁盘的文件系统,该结构对应磁盘上的”文件数据控制块”。每一个inode结构都对应一个inode节点号,这个节点号是唯一的,它也唯一标识一个文件系统中的文件。
file结构( struct file {…} ) 文件对象
该结构中存储的是一个打开的文件和打开这个文件的进程间的交互信息。该结构保存在kernel的内存区,在打开文件时被创建,关闭文件时被释放。
dentry结构( struct dentry {…} ) 目录项对象
该结构存储的是目录实体和对应的文件的关联信息。
下图是一个简单示例,说明进程是怎样与文件进行交互。三个不同进程打开同一个文件,其中两个进程使用同一个硬链接(每个硬链接对应一个目录对象),其中每个进程都使用自己的文件对象。
与VFS有关的系统调用:
VFS是应用程序和具体文件系统之间的一层。不过,在某些情况下,一个文件操作可能由VFS本身去执行,无需调用底层函数。例如,当某个进程关闭一个打开的文件时,并不涉及磁盘上的相应文件,因此VFS只需释放相应的文件对象。类似的,当系统调用lseek()修改一个文件指针,而这个文件指针是打开文件与进程交互所涉及的一个属性时,VFS就只需修改相应的文件对象,而不必访问磁盘上的文件。因此,无需调用具体文件系统函数。从某种意义上说,可以把VFS看成“通用”文件系统,它在必要时依赖某种具体的文件系统。
VFS的数据结构
每个VFS对象都存放在一个适当的数据结构中,其中包括对象的属性和指向对象方法表的指针。内核可以动态的修改对象的方法,因此可以为对象建立专用的行为。
struct super_block {
struct list_head s_list; /* 指向超级块链表的指针 */
dev_t s_dev; /* 设备标示符t */
unsigned long s_blocksize; 块大小(以字节为单位)
unsigned char s_blocksize_bits; 以位为单位的块大小
unsigned char s_dirt; 修改(脏)标志
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; 引用计数
int s_need_sync;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
#endif
struct xattr_handler **s_xattr; 指向超级块扩展属性结构的指针
struct list_head s_inodes; /* 所有索引节点链表 */
struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_files; 文件对象链表
/* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
struct list_head s_dentry_lru; /* unused dentry lru */
int s_nr_dentry_unused; /* # of dentry on lru */
struct block_device *s_bdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct list_head s_instances;
struct quota_info s_dquot; /* Diskquota specific options */
int s_frozen;
wait_queue_head_t s_wait_unfrozen;
char s_id[32]; /* Informational name */
void *s_fs_info; /* 指向具体文件系统的超级块信息。比如,当超级块指向的是Ext2文件系统,该字段就指向ext2_sb_info数据结构。通常为了效率起见,由s_fs_info指向的数据结构被复制到内存,当对其进行操作时就无需实际访问磁盘,同时为了解决VFS与实际磁盘同步问题,而引入一个s_dirty标志来表示该超级块是否脏。linux定期性的将“脏”数据同步到磁盘上 */
fmode_t s_mode;
/*
* 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 */
/* Granularity of c/m/atime in ns.