2011。9。5更新
之前好像想的太多了,估计也有点绕弯。
三分部分结构目录项、inode节点、数据项
目录项 对应 DIR dirent 在<dirent.h>文件中定义,包含__ino_t __off_t d_type d_name//这里没有记录当前目录的名称
对应的常用操作就是opendir readdir那些
inode节点对应 inode,但是stat 这个结构里基本包含了用的到的属性信息//目前还是分不清这俩是怎么操作的,不过先不管了
对应的操作stat()函数 <sys/stat.h>
FILE是标准IO的封装,<stdio.h>
刚开始文件系统有挂载的概念,这时候就找到了挂载点的目录项对应的节点信息
pwd命令可以自行实现:通过stat取得当前的inode节点thisnode,然后chdir到..目录,比较..中各个目录项节点=thisnode的然后打印出消息来。然后再chdir到..重复以上操作。
之前写的疑惑部分没有更新,一是想多了二是不知道怎么弄,还是先走之前说的知识屏蔽的路线把
====================分割现
真的是浅析,好多疑问,好多没概念,好多猜想。很需要朋友的拍砖指导
在笔记(一):IO效率里只是理解了个缓冲个概念,这次接着三四章看看文件和目录结构,以及对应的文件IO。
这里文件和目录结构 是数据结构的概念,总的来说文件系统是一个树形结构,是将如何将文件存储到介质上
文件IO,是针对树形数据结构的一些操作,牵扯到process\牵扯到进程。那就从这两方面入手记录一下
1、文件系统的实现-存储数据结构
上图中是文件系统总的结构图,分区partition、柱面cylinder group这里就先屏蔽掉,知道他是一个结构的概念(王爽的汇编教材里提到了知识屏蔽的概念,我看这本书看得很过瘾,遗憾没早点接触),这个图里重点关注inode,inode基本包含了文件的所有信息如下:
struct inode {
unsigned long i_ino; //i节点号,一个文件对应一个唯一的i节点号
unsigned int i_nlink; //文件的硬链接数
struct timespec i_atime; //文件最后一次被访问的时间
struct timespec i_mtime; //文件内容最后一次被修改的时间
struct timespec i_ctime; //文件inode被修改的时间
unsigned long i_blocks; //文件的所占的块数
struct inode_operations *i_op; //inode的操作接口
struct file_operations *i_fop; //默认的文件操作former->i_op->default_file_ops
struct super_block *i_sb; //指向超级块结构
struct file_lock *i_flock; //文件锁指针
struct address_space *i_mapping; //
struct address_space i_data;
struct pipe_inode_info *i_pipe; //如果文件是一个管道
struct block_device *i_bdev; //指向块设备驱动程序
struct cdev *i_cdev; //指向字符设备驱动程序
unsigned long i_state; //inode的状态标识符
};
这里没有的是文件的名字,平时我们都是以文件的名字来对文件进行索引,感觉文件的名称应该是
文件的主键,其实文件的名字也就是文件的一个属性,文件名称放在了目录块中。至于为什么不放
在inode中,而放在目录块中。目前我的猜想是为了方便文件的迅速查找索引然后装载到内存中?
随后我会实现一个pwd命令的程序。
这里这个图显示的是新建一个文件夹testdir的时候,索引的指向
先看右边,第一个entry表明它的filename是dot,它的i-node number是1267,那么它就代表一个i-node,这个i-node的file type是directory。它新建一个目录,filename是testdir,i-node number是2549,它指向一个新的i-node,这个i-node 的file type也是directory。这个i-node指向一个directory block,这个block中存放着有关2549这个目录的信息
这两图也能解释软链和硬链的区别,以及同一个文件系统下剪切文件的速度为啥那么快(可以自己翻看apue或者gogle)
2、linux进程对文件系统的访问
内核使用上图中的三种数据结构表示打开的文件。
(一)进程表中记录项:文件描述符标志+文件指针
(二)文件表:文件状态+偏移量+指向文件V节点指针
(三)V节点表:文件类型+文件操作函数指针+inode
这个结构支持多个进程打开同一个文件(两个文件表项指向同一个V节点表,但是文件状态和偏移量不同)也支持dup函数(两个文件指针指向同一个文件表,文件状态和偏移量以及v节点都一样)
以上讲的都是书上的概念性的东西,至于内核系统真正打开文件是怎么个过程细节如何,我却是越查越糊涂
疑问1:这是我找到的系统打开文件时候的一个结构。这里面我想还原上面三个结构,却是没有还原出来,
希望有了解的给我指点指点。
file结构主要保存进程打开一个文件时的交互信息,该结构的内容不是保存在磁盘上,而是保存在内存中的。当进程打开一个文件时,该结构被创建。进程打开文件时创建的数据结构如此:
task_struct-->files_struct-->file
下面看一下file结构的具体内容:
struct file {
struct list_head f_list;
struct dentry *f_dentry; //与文件结构对应的dentry
struct vfsmount *f_vfsmnt; //装载的文件系统中包含了该文件
struct file_operations *f_op; //文件操作表
atomic_t f_count; //文件对象被引用的数
unsigned int f_flags; //
mode_t f_mode; //进程访问方式
int f_error;
loff_t f_pos; //目前文件偏移量(文件指针的位置)
struct fown_struct f_owner;
unsigned int f_uid, f_gid; //用户的UID和GID
struct file_ra_state f_ra;
size_t f_maxcount;
unsigned long f_version;
void *f_security;
void *private_data;
struct address_space *f_mapping; //指向文件的地址空间结构
};
该结构中一个重要的项就是f_pos,因为几个进程可能同时打开一个文件,而每个进程对文件的操作不一样,偏移量也对每个进程不一样,所以f_pos应该在struct file中,而不应该在inode结构中。
疑问2:
apue第四张基本上是围绕着struct stat这个结构体展开的,如果上面的struct file结构是如何取的呢。
struct stat
{
dev_t st_dev; /* ID of device containing file -文件所在设备的ID*/
ino_t st_ino; /* inode number -inode节点号*/
mode_t st_mode; /* protection -保护模式?*/
nlink_t st_nlink; /* number of hard links -链向此文件的连接数(硬连接)*/
uid_t st_uid; /* user ID of owner -user id*/
gid_t st_gid; /* group ID of owner - group id*/
dev_t st_rdev; /* device ID (if special file) -设备号,针对设备文件*/
off_t st_size; /* total size, in bytes -文件大小,字节为单位*/
blksize_t st_blksize; /* blocksize for filesystem I/O -系统块的大小*/
blkcnt_t st_blocks; /* number of blocks allocated -文件所占块数*/
time_t st_atime; /* time of last access -最近存取时间*/
time_t st_mtime; /* time of last modification -最近修改时间*/
time_t st_ctime; /* time of last status change - */
};
看到stat想起之前获取文件长度的方法
FILE *f=fopen(filename,"r“);
fseek(f,0,SEEK_END);
long length=ftell(f);
这样的话是不是真有个移动偏移量到文件尾部的过程呢(还得需要看内核!!!),就算不移动两个函数的调用加基本操作开销也算不小了
struct stat f_stat;
stat(filename,&f_stat);
long length=f_stat.st_size;
这样就轻便些了。 这一点应该是这俩章唯一的收获了
下图是关于带文件锁的结构图,以后再回过头来看留作备份
3、文件结构与文件IO的映射
这一张图也是提供一个文件存储结构于内存文件结构的区别概念。以后自己来完善这张图。
此致,希望朋友们拍砖指导,我很疑惑这些。