APUE笔记(二):文件系统浅析

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、文件系统的实现-存储数据结构

disk drive partitions and file system

上图中是文件系统总的结构图,分区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命令的程序。


image

这里这个图显示的是新建一个文件夹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;

这样就轻便些了。 这一点应该是这俩章唯一的收获了



下图是关于带文件锁的结构图,以后再回过头来看留作备份

文件锁机制 - linux-ul - unix-EA


3、文件结构与文件IO的映射

这一张图也是提供一个文件存储结构于内存文件结构的区别概念。以后自己来完善这张图。


此致,希望朋友们拍砖指导,我很疑惑这些。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值