linux文件系统之路径查找与文件系统的挂载.docx
- 文档编号:9958735
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:97
- 大小:69.31KB
linux文件系统之路径查找与文件系统的挂载.docx
《linux文件系统之路径查找与文件系统的挂载.docx》由会员分享,可在线阅读,更多相关《linux文件系统之路径查找与文件系统的挂载.docx(97页珍藏版)》请在冰豆网上搜索。
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
//最后的结点需要是一个目录
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 文件系统 路径 查找