from : http://blog.chinaunix.net/uid-26827166-id-3628658.html
第六章 虚拟文件系统
第一节 目录缓存
d_invalidate
函数概述 | 注销一个目录 |
函数原型 | int d_invalidate(struct dentry* dentry) |
参数说明 | dentry----需要注销的目录 |
函数用法 | 检查是否有权利注销目录,如果有其他目录与这个目录关联,此时不可用。同时返回EBUSY 注销成功返回 0 不包含目录缓存 |
函数概述 | 在hash列表中找出一个inode的别名 |
函数原型 | struct dentry* d_find_alias(struct inode* inode) |
参数说明 | inode---需要查找的inode指针 |
函数用法 | 如果inode在哈希列表中有别名,则可以通过这个函数获取这个别名的参考同时返回这个值。否则返回NULL 注意,如果inode是目录项,只能有一个别名,而且只有没有子目录的时候才能被反哈希查找。 |
函数概述 | 缩小目录缓存的大小 |
函数原型 | void prune_dcache(int count) |
参数说明 | count---需要缩小的目录缓存数 |
函数用法 | 减少目录缓存的大小。这个函数在系统需要内存资源的时候用的到,或者当我们unmount一个对象的时候, 都会调用到这个函数。如果需要回收的对象正在被系统使用,就会报错。 |
shrink_dcache_sb
函数概述 | 为超级块缩小目录缓存 |
函数原型 | void shrink_dcache_sb( struct super_block* sb) |
参数说明 | sb-----目标超级块 |
函数用法 | 为规定好的超级块减少目录缓存的大小。这个函数在卸载文件系统之之前执行 |
have_submounts
函数概述 | 检查目标条目是否存在挂在点 |
函数原型 | int have_submounts(struct dentry* parent) |
参数说明 | parent----被检查的条目 |
函数用法 | 如果目标目录的父目录或者子目录中有挂载点的话,返回TRUE |
shrink_dcache_parent
函数概述 | 截断目录缓存 |
函数原型 | void shrink_dcache_parent(struct dentry* parent) |
参数说明 | parent---目标目录的父目录 |
函数用法 | 删除父目录中未在使用中的子目录缓存 |
d_alloc
函数概述 | 分配一个新的目录缓存项 |
函数原型 | struct dentry* dalloc(struct dentry* parent, const struct qstr* name) |
参数说明 | parent----需要被分配的条目的父目录 name-----目录名字的qstr结构* |
函数用法 | 分配一个目录,如果没有足够的可用内存,则分配失败,返回NULL,创建成功则返回目录首地址 |
d_instantiate
函数概述 | 向一个新建的目录项中添加inode信息 |
函数原型 | void d_instantiate(struct dentry* entry, struct inode* inode) |
参数说明 | entry----需要实例化的目录项 inode----将会与这个目录项关联的inode节点指针 |
函数用法 | 向目录项中填充inode的基本信息 |
d_alloc_root
函数概述 | 分配根目录 |
函数原型 | struct dentry* d_alloc_root(struct inode* root_inode) |
参数说明 | root_inode----用于根节点的inode |
函数用法 | 为给定的inode节点分配一个根目录,随后将这个节点实例化并返回。如果内存不够则返回NULL |
d_lookup
函数概述 | 查找目录入口地址 |
函数原型 | struct dentry* d_lookup(struct dentry* parent, struct qstr* name) |
参数说明 | parent----父目录 name-----目录的qstr结构名字 |
函数用法 | 查找给定的目录的子目录,如果发现目标目录项的引用数非零,调用本函数者必须首先调用d_put 在释放目录引用项之后进行查找。 |
d_validate
函数概述 | 验证由非安全源获得的目录项 |
函数原型 | int d_validate(struct dentry* dentry, struct dentry* dparent) |
参数说明 | dentry-----需要验证的子目录指针 parent-----给定的合法的父目录 |
函数用法 | 当获得一个未知的目录地址时,应该使用这个函数来验证其合法性。如果地址不合法则返回 0 |
d_delete
函数概述 | 删除一个目录 |
函数原型 | void d_delete(struct dentry* dentry) |
参数说明 | dentry----需要删除的目录指针 |
函数用法 | 如果不能删除,则先从哈希队列中删除记录,随后删除 |
d_rehash
函数概述 | 向哈希表添加一个新的注册项 |
函数原型 | void d_rehash(struct dentry* dentry) |
参数说明 | dentry-----需要注册到哈希表的目录项指针 |
函数用法 | 根据目标地址的名字注册到哈希列表中 |
d_move
函数概述 | 移动一个目录项,重命名 |
函数原型 | void d_move(struct dentry* dentry, struct dentry* taget) |
参数说明 | dentry-----需要重命名的目录项 target-----目标目录项 |
函数用法 | 完成重命名之后,需要更新目录缓存,已经注册删除的目录项不能进行重命名操作 |
__d_path
函数概述 | 返回一个目录项的地址 |
函数原型 | char* __d_path(struct dentry* dentry, struct vfsmount* vfsmnt, struct dentry* root, struct vfsmount* rootmnt, char* buffer, int buflen) |
参数说明 | dentry----需要查询的目录项指针 vfsmnt----需要查询的目录项所挂载的虚拟文件系统挂载点 root-------根目录地址 rootmnt--根目录所在的虚拟挂载点 buffer-----缓存地址项 buflen-----缓存的大小 |
函数用法 | 将一个目录项转换成ASCII格式的文件路径,如果文件已删除,则返回deleted。 注意转换过程是模糊不清的。buflen大小至少是page_size,调用者需要维护一个 dcache_lock锁 |
is_subdir
函数概述 | 验证两个目录之间是否有继承关系 |
函数原型 | int is_subdir(struct dentry* new_dentry, struct dentry* old_dentry) |
参数说明 | new_dentry---需要验证的假定子目录 old_dentry----需要验证的假定父目录 |
函数用法 | 如果新目录是老目录的子目录,则返回 1 |
find_inode_number
函数概述 | 通过名字查看目录项 |
函数原型 | ino_t find_inode_number(struct dentry* dir, struct qstr* name) |
参数说明 | dir-----需要查找的目录项的路径 name-需要查找的目录项的名字 |
函数用法 | 检查给定的目录名是否存在,如果inode存在,则返回inode标号 |
d_drop
函数概述 | 降低一个目录项哈希表等级 |
函数原型 | void d_drop(struct dentry* dentry) |
参数说明 | dentry---需要降级的目录项 |
函数用法 | d_drop通过反哈希算法找出父目录的哈希表值 |
d_add
函数概述 | 向哈希列表中添加一个目录项 |
函数原型 | void d_add(struct dentry* entry, struct inode* inode) |
参数说明 | entry----需要添加的目录项指针 inode-----需要添加的目录项绑定的inode |
函数用法 | 本函数将目录项添加到哈希列表并初始化inode,真正将目录项添加进去是在d_alloc分配目录项位置之后 |
dget
函数概述 | 获取目录项的引用 |
函数原型 | struct dentry* dget(struct dentry* dentry) |
参数说明 | dentry----需要获取引用的目标目录项 |
函数用法 | 如果目录项尚未引用,而且其引用项已经加锁,应该先调用dget_locked来获取dcache_lock锁 |
d_unhashed
函数概述 | 验证哈希表中是否有目标目录项 |
函数原型 | int d_unhashed(struct dentry* dentry) |
参数说明 | dentry---需要检查的目标目录项 |
函数用法 | 如果目录项不在当前哈希表中,则返回TRUE |
第二节 节点控制
__mark_inode_dirty
函数概述 | 内部函数,标记一个inode是否包含脏数据 |
函数原型 | void __mark_inode_dirty(struct inode* inode, int flags) |
参数说明 | inode----被标记的inode节点 flags-----脏数据的类型 |
函数用法 |
write_inode_dirty
函数概述 | 将inode数据写入磁盘 |
函数原型 | void write_inode_now(struct inode* inode, int sync) |
参数说明 | inode----被写入磁盘的inode数据项 sync-----写操作是否需要进行数据同步 |
函数用法 | 本函数检查inode,如果查出脏数据,立刻对磁盘进行数据更新。本函数作为knfsd的首选项之一 |
clear_inode
函数概述 | 清除一个inode节点 |
函数原型 | void clear_inode(struct inode* inode) |
参数说明 | inode----需要被清除的节点指针 |
函数用法 | 由文件系统调用,通知用户本节点不能使用。随后,我们就冷酷的把这个节点处理掉 |
invalidate_inodes
函数概述 | 抛弃设备挂载的inode节点信息 |
函数原型 | int invalidate_inodes(struct super_block* sb) |
参数说明 | sb------设备相关的超级块 |
函数用法 | 在给定的超级块中放弃所有的inode节点信息。 |
get_empty_inode
函数概述 | 获取一个空白inode |
函数原型 | struct inode* get_empty_inode(void) |
参数说明 | void |
函数用法 | 本函数由上层调用,用于使用inode之前,调用空白inode.调用成功后,返回inode指针 |
iunique
函数概述 | 获取一个唯一的inode号 |
函数原型 | ino_t iunique(struct super_block* sb, ino_t max_reserved) |
参数说明 | sb-------目标超级块 max_reserved-最高级的inode号 |
函数用法 | 对于给定的超级块来说,此处获取的inode号是惟一的,可以被文件系统识别调用。 |
insert_inode_hash
函数概述 | 在哈希列表中添加inode项 |
函数原型 | void insert_inode_hash(struct inode* inode) |
参数说明 | inode----需要被添加到哈希表的inode指针 |
函数用法 | 添加到超级块注册区域内的哈希表呢,如果没有所属的超级块,则添加到匿名块中 |
remove_inode_hash
函数概述 | 将inode从哈希表中移除 |
函数原型 | void remove_inode_hash(struct inode* inode) |
参数说明 | inode----需要被移除的inode指针 |
函数用法 | 从超级块区域内的哈希表或者匿名块中移除指定inode注册信息 |
iput
函数概述 | 移动一个inode |
函数原型 | void iput(struct inode* inode) |
参数说明 | inode----需要被移动的inode指针 |
函数用法 | 移动一个inode同时减少使用计数,当计数为0 时,需要调用释放或销毁函数 |
bmap
函数概述 | 在一个文件中找到块号 |
函数原型 | int bmap(struct inode* inode, int block) |
参数说明 | inode-----文件对应的inode节点指针 block-----需要找到并返回的块号 |
函数用法 |
update_time
函数概述 | 更新访问时间 |
函数原型 | void update_atime(struct inode* inode) |
参数说明 | inode----需要更新的inode节点 |
函数用法 | 更新inode的访问时间,本函数用于处理只读文件系统和媒体对象 |
make_bad_inode
函数概述 | 标记因为I/O出现的错误inode |
函数原型 | int mark_bad_inode(struct inode* inode) |
参数说明 | inode-----被标记的inode对象 |
函数用法 | 如果被标记过错误,此处返回TRUE |
is_bad_inode
函数概述 | 检查是否出现inode错误 |
函数原型 | int is_bad_inode(struct inode* inode) |
参数说明 | inode-----被检查的inode对象 |
函数用法 | 如果被标记过错误,此处返回TRUE |
第三节 文件系统注册及超级块
register_filesystem
函数概述 | 注册一个新的文件系统 |
函数原型 | int register_filesystem(struct file_system_type* fs) |
参数说明 | fs-----文件系统的类型指针 |
函数用法 | 向系统注册一个新的文件系统,同时挂载这个文件系统 |
unregister_filesystem
函数概述 | 注销一个文件系统 |
函数原型 | nt unregister_filesystem(struct file_system_type* fs) |
参数说明 | fs-----文件系统的类型指针 |
函数用法 | 从系统注销新建的文件系统,同时卸载这个文件系统 |
get_super
函数概述 | 获取设备的超级块 |
函数原型 | struct super_block* get_super(kdev_t dev) |
参数说明 | dev----需要获取超级块的设备指针 |
函数用法 | 扫描超级块列表找到需要查找的超级块,如果没有查找到返回NULL |
第四节 文件锁
posix_lock_file
函数概述 | 给文件添加一个POSIX锁 |
函数原型 | int posix_lock_file(struct file* filp, struct file_lock* caller, unsigned int wait) |
参数说明 | filp----需要添加文件锁的文件指针 caller--文件锁的对象指针 wait----1等待锁,0返回EAGAIN获取失败 |
函数用法 | 向文件添加锁,锁都是成对出现的,POSIX锁依据用户任务排序。 |
小结
本章中的函数与机制关联度非常大,所以在每一个函数后边都添加了机制相关的内容,想通过这些东西给大家
简要的普及驱动开发所需API的基本使用方法。
当然,百说不如一用,尝试着将API应用到自己的编写的模块中并安装使用才是王道。
蒙幸能参加知名IT公司实习,也是做驱动部分,希望能在这个岗位中学到更多东西,如果能个师傅那就更靠谱了。
废话不多说,明天继续更网络部分API敬请,期待