linux文件系统之路径查找与文件系统的挂载.docx

上传人:b****1 文档编号:3158762 上传时间:2023-05-05 格式:DOCX 页数:97 大小:69.31KB
下载 相关 举报
linux文件系统之路径查找与文件系统的挂载.docx_第1页
第1页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第2页
第2页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第3页
第3页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第4页
第4页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第5页
第5页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第6页
第6页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第7页
第7页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第8页
第8页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第9页
第9页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第10页
第10页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第11页
第11页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第12页
第12页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第13页
第13页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第14页
第14页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第15页
第15页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第16页
第16页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第17页
第17页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第18页
第18页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第19页
第19页 / 共97页
linux文件系统之路径查找与文件系统的挂载.docx_第20页
第20页 / 共97页
亲,该文档总共97页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

linux文件系统之路径查找与文件系统的挂载.docx

《linux文件系统之路径查找与文件系统的挂载.docx》由会员分享,可在线阅读,更多相关《linux文件系统之路径查找与文件系统的挂载.docx(97页珍藏版)》请在冰点文库上搜索。

linux文件系统之路径查找与文件系统的挂载.docx

linux文件系统之路径查找与文件系统的挂载

linux文件系统之路径查找与文件系统的挂载

------------------------------------------

本文系本站原创,欢迎转载!

转载请注明出处:

------------------------------------------

文件系统是操作系统的一个重要的功能,linux提供了对各种文件系统的支持,具有极高的扩展性.文件系统这一部份也是linux内核中难以理解的一部份,因为它与很多子系统有关.有时候还需要涉及到具体的磁盘分区格式.下面的代码分析以ext2格式为基础进行分析.在分析的过程中会遇到了块设备操作的一些API,暂且将它放至一边。

块设备的操作会以单独的专题做讨论。

一:

与关系统有关的数据结构

1.1:

VFS相关的数据结构

在文件系统中,涉及到最多的就是super_block,inode,dentry这几个结构。

先列出这几个结构中各成员所代表的含义,具体的作用等到代码遇到再进行分析。

这几个结构在内核中的定义如下:

structsuper_block{

//用来形成一个链表

    structlist_head  s_list;      /*Keepthisfirst*/

    //super_block所对应的设备

    dev_t             s_dev;       /*searchindex;_not_kdev_t*/

    //以字节为单位的块大小

    unsignedlong     s_blocksize;

    unsignedlong     s_old_blocksize;

    //以位为单位的块大小

    unsignedchar     s_blocksize_bits;

    //“脏”标志

    unsignedchar     s_dirt;

    //文件大小的上限

    unsignedlonglongs_maxbytes;  /*Maxfilesize*/

    //所属的文件系统

    structfile_system_type*s_type;

    //super_block的操作

    structsuper_operations*s_op;

    //磁盘限额的方法

    structdquot_operations*dq_op;

    //配置磁盘限额的方法

    structquotactl_ops   *s_qcop;

    //导出的方法

    structexport_operations*s_export_op;

    //所对应的标志

    unsignedlong     s_flags;

    //文件系统的魔数

    unsignedlong     s_magic;

    //目录登录点

    structdentry    *s_root;

    //为避免竞争,所用的rw_semaphore

    structrw_semaphore   s_umount;

    structsemaphore  s_lock;

    int          s_count;

    //文件系统的同步标志

    int          s_syncing;

    //尚末将文件系统同步

    int          s_need_sync_fs;

    //活动引用计数

    atomic_t     s_active;

    //安全模块

    void                   *s_security;

    structxattr_handler  **s_xattr;

    //脏节点链表

    structlist_head  s_dirty;/*dirtyinodes*/

    //回写链表

    structlist_head  s_io;        /*parkedforwriteback*/

    //匿名分区

    structhlist_head s_anon;      /*anonymousdentriesfor(nfs)exporting*/

    //被分区的文件链表

    structlist_head  s_files;

    //相关的块设备

    structblock_device   *s_bdev;

    //该类型的文件系统

    structlist_head  s_instances;

    structquota_info s_dquot;/*Diskquotaspecificoptions*/

    //如果该标志被置位,则禁止使用该文件系统(可能需要等待某些操作的完成,例如同步)

    int          s_frozen;

    //等待队列

    wait_queue_head_t s_wait_unfrozen;

    //设备的名称

    chars_id[32];                  /*Informationalname*/

    //指向特定的文件系统的信息(这个是一个统一的结构,毕竟不同的文件系统有很多不同的信息)

    void             *s_fs_info;  /*Filesystemprivateinfo*/

 

    /*

     *ThenextfieldisforVFS*only*.Nofilesystemshaveanybusiness

     *evenlookingatit.Youhadbeenwarned.

     */

     //删除时使用的信号量

    structsemaphores_vfs_rename_sem;  /*Kludge*/

}

 

structinode{

    //散列表

    structhlist_node i_hash;

    //用来形成链表

    structlist_head  i_list;

    //目录项链表

    structlist_head  i_dentry;

    //索引节点号

    unsignedlong     i_ino;

    //引用计数

    atomic_t     i_count;

    //访问权根控制

    umode_t           i_mode;

    //硬链接数目

    unsignedint      i_nlink;

    //使用者id

    uid_t             i_uid;

    //使用者的gid

    gid_t             i_gid;

    //所属的设备

    dev_t             i_rdev;

    //以字节为单位的文件大小

    loff_t            i_size;

    //最后访问时间

    structtimespec       i_atime;

    //最后修改时间

    structtimespec       i_mtime;

    //最后改变时间

    structtimespec       i_ctime;

    //以位为单位的块大小

    unsignedint      i_blkbits;

    //以字节为单位的块大小

    unsignedlong     i_blksize;

    //版本号

    unsignedlong     i_version;

    //文件的块数

    unsignedlong     i_blocks;

    //使用的字节数

    unsignedshort         i_bytes;

    //如果该成员被置为1```则这个inode表示的是一个套接字

    unsignedchar     i_sock;

    //索引结点的自旋锁

    spinlock_t        i_lock; /*i_blocks,i_bytes,maybei_size*/

    //索引结点的信号量

    structsemaphore  i_sem;

    structrw_semaphore   i_alloc_sem;

    //索引结点的操作列表

    structinode_operations*i_op;

    //索引结点所属文件的操作列表

    structfile_operations*i_fop; /*former->i_op->default_file_ops*/

    //索引结点的所属super_block

    structsuper_block*i_sb;

    //文件锁链表

    structfile_lock  *i_flock;

    //把向所属的页面缓存

    structaddress_space  *i_mapping;

    structaddress_space  i_data;

#ifdefCONFIG_QUOTA

    structdquot      *i_dquot[MAXQUOTAS];

#endif

    /*Thesethreeshouldprobablybeaunion*/

    //块设备链表

    structlist_head  i_devices;

    //管道信息

    structpipe_inode_info*i_pipe;

    //所属块设备

    structblock_device   *i_bdev;

    //所属的字符设备

    structcdev       *i_cdev;

    int          i_cindex;

    //索引结点的版本号

    __u32           i_generation;

    //目录通知掩码

    unsignedlong     i_dnotify_mask;/*Directorynotifyevents*/

    //目录通知

    structdnotify_struct *i_dnotify;/*fordirectorynotifications*/

    //状态标志

    unsignedlong     i_state;

    //首次修改时间

    unsignedlong     dirtied_when;/*jiffiesoffirstdirtying*/

    //文件系统标志

    unsignedint      i_flags;

    //写者计数

    atomic_t     i_writecount;

    //安全模块

    void         *i_security;

    //文件的特殊信息

    union{

        void    *generic_ip;

    }u;

#ifdef__NEED_I_SIZE_ORDERED

    seqcount_t        i_size_seqcount;

#endif

}

 

structdentry{

    //引用计数

    atomic_td_count;

    //目录项标识

    unsignedintd_flags;      /*protectedbyd_lock*/

    //单目录项

    spinlock_td_lock;    /*perdentrylock*/

    //相关的inode

    structinode*d_inode;     /*Wherethenamebelongsto-NULLis

                       *negative*/

    /*

     *Thenextthreefieldsaretouchedby__d_lookup. Placethemhere

     *sotheyallfitina16-byterange,with16-bytealignment.

     */

     //父目录中的目录结构

    structdentry*d_parent;   /*parentdirectory*/

    //散队表头

    structhlist_head*d_bucket;    /*lookuphashbucket*/

    //目录项的名字

    structqstrd_name;

    //LRU链表

    structlist_headd_lru;    /*LRUlist*/

    //父目录的子目录链表

    structlist_headd_child;  /*childofparentlist*/

    //目录的子目录链表

    structlist_headd_subdirs;/*ourchildren*/

    //索引结点的别名链表

    structlist_headd_alias;  /*inodealiaslist*/

    //重新生效的时间

    unsignedlongd_time;      /*usedbyd_revalidate*/

    //目录项的操作列表

    structdentry_operations*d_op;

    //目录项的所属super_block

    structsuper_block*d_sb;  /*Therootofthedentrytree*/

    

    void*d_fsdata;            /*fs-specificdata*/

    void*d_extra_attributes; /*TUX-specificdata*/

    //RCU锁

    structrcu_headd_rcu;

    structdcookie_struct*d_cookie;/*cookie,ifany*/

    //所属散列表

    structhlist_noded_hash;  /*lookuphashlist*/

    //是否有文件系统被挂载到此目录下

    intd_mounted;

    //短文件名

    unsignedchard_iname[DNAME_INLINE_LEN_MIN];  /*smallnames*/

}

 

在这里要注意的是,不管目录还是普通文件在文件系统中都是对应的文件,只是文件的类型不一样,都有一个dentry项,dentry项对应一个inode.inode和dentry都有一个成员指向文件系统的super_block.

 

1.2:

与进程相关的结构

在task的定义中,包含两个成员:

fs,file.它们的结构定义如下所示:

structfs_struct{

    //结构的引用计数

    atomic_tcount;

    //读写锁

    rwlock_tlock;

    //默认的文件访问权限

    intumask;

    //用户的root目录,当前目录,与替换目录

    structdentry*root,*pwd,*altroot;

    //root目录,当前目录与替换目录所对应的文件系统

    structvfsmount*rootmnt,*pwdmnt,*altrootmnt;

}

其中,在x86平台中,altroot与altrootmnt的值为空.

 

File对应的数据结构为files_struct.它的结构定义如下:

structfiles_struct{

    //结构体的使用计数

       atomic_tcount;

       spinlock_tfile_lock;    /*Protectsallthebelowmembers. Nestsinsidetsk->alloc_lock*/

    //文件对象数的上限

       intmax_fds;

    //文件描述符的上限

       intmax_fdset;

    //下一个文件描述符

       intnext_fd;

    //全部文件对象数组

       structfile**fd;     /*currentfdarray*/

    //exec()关闭的文件描述符

       fd_set*close_on_exec;

    //打开的文件描述符指针

       fd_set*open_fds;

    //exe()关闭的初始化文件

       fd_setclose_on_exec_init;

    //文件描述符的初始集合

       fd_setopen_fds_init;

    //默认的文件对象数组

       structfile*fd_array[NR_OPEN_DEFAULT];

}

 

 

二:

路径名的查找

在应用中,经常有为给定的路径寻找结点的操作,例如cd/home/eric/kernel_study.这个操作是经常需用用到的操作,在进行深入的文件系统学习前,有必要先了解一下这个操作的实现.

在内核中,path_lookup()用来查到一个给定路径的所属文件结点。

它的代码如下:

intfastcallpath_lookup(constchar*name,unsignedintflags,structnameidata*nd)

{

    intretval;

 

    //刚开始搜索前,将nd->last_type置为LAST_ROOT

    nd->last_type=LAST_ROOT;/*ifthereareonlyslashes...*/

    nd->flags=flags;

    nd->depth=0;

 

    //为了避免对current->fs的读写竞争,先加锁

    read_lock(¤t->fs->lock);

    //第一个路径字符为'/',表示的是一个绝对路径.eg:

/home/eric

    if(*name=='/'){

        //在x86中,task->fs->altroot为空

        if(current->fs->altroot&&!

(nd->flags&LOOKUP_NOALT)){

             nd->mnt=mntget(current->fs->altrootmnt);

             nd->dentry=dget(current->fs->altroot);

             read_unlock(¤t->fs->lock);

             if(__emul_lookup_dentry(name,nd))

                  return0;

             read_lock(¤t->fs->lock);

        }

        //将搜索的起始路径设为root

        nd->mnt=mntget(current->fs->rootmnt);

        nd->dentry=dget(current->fs->root);

    }else{

    //相对路径.eg:

eric/kernel_study

    //将搜综的起始路径设为pwd

        nd->mnt=mntget(current->fs->pwdmnt);

        nd->dentry=dget(current->fs->pwd);

    }

    //解锁

    read_unlock(¤t->fs->lock);

    //将当前进程的total_link_count置为0(表示末遇到链接)

    current->total_link_count=0;

    retval=link_path_walk(name,nd);

    if(unlikely(current->audit_context

            &&nd&&nd->dentry&&nd->dentry->d_inode))

        audit_inode(name,

                nd->dentry->d_inode->i_ino,

                nd->dentry->d_inode->i_rdev);

    returnretval;

}

这个函数有三个参数:

name表示路径的字符串。

Flag表示搜索的标志.如下所示:

 

//如果最后一个结点是符号链表,跟随进去

#defineLOOKUP_FOLLOW      1

//最后的结点需要是一个目录

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2