收藏 分销(赏)

Linux VFS中close系统调用实现原理.doc

上传人:pc****0 文档编号:8988837 上传时间:2025-03-10 格式:DOC 页数:4 大小:48KB
下载 相关 举报
Linux VFS中close系统调用实现原理.doc_第1页
第1页 / 共4页
Linux VFS中close系统调用实现原理.doc_第2页
第2页 / 共4页
点击查看更多>>
资源描述
Linux VFS中close系统调用实现原理 目录 close系统调用在内核里面的入口函数为sys_close 根据用户空间传入的文件描述符fd取出对应的struct file结构体 清空进程的文件描述符fd所对应的标准位,如果要关闭的这个的文件描述符对应的fd小于下一次的文件描述符起点,则根系下一次本进程的文件描述符起点为fd 释放struct file结构体 所以,只有调用了sys_close系统调用,进程的所有文件列表中才会把这个文件删除 WORD里面的目录复制过来似乎不能直接用。。还是放在这里当主线看吧.. close系统调用在内核里面的入口函数为sys_close [root@syslab ~]# grep close /usr/include/asm/unistd_64.h #define __NR_close 3 __SYSCALL(__NR_close, sys_close) SYSCALL_DEFINE1(close, unsigned int, fd) {{//这里SYSCALL_DEFINE1 close到sys_close的转换请参看前面的文章Linux 编程中的API函数和系统调用的关系 struct file * filp; struct files_struct *files = current->files; struct fdtable *fdt; int retval; spin_lock(&files->file_lock); fdt = files_fdtable(files); if (fd >= fdt->max_fds) goto out_unlock; filp = fdt->fd[fd]; if (!filp) goto out_unlock; rcu_assign_pointer(fdt->fd[fd], NULL); __clear_close_on_exec(fd, fdt); __put_unused_fd(files, fd); spin_unlock(&files->file_lock); retval = filp_close(filp, files); …//省略次要 } 函数不长,流程主要如下 根据用户空间传入的文件描述符fd取出对应的struct file结构体 方便理解,我写成Struct file filt=current->files_struct->fdtable->files[fd]; (current是当前task_struct) 清空进程的文件描述符fd所对应的标准位,如果要关闭的这个的文件描述符对应的fd小于下一次的文件描述符起点,则根系下一次本进程的文件描述符起点为fd __clear_close_on_exec(fd, fdt);//执行__clear_bit(fd, fdt->close_on_exec);操作,即在close_on_exec中把fd位的设置为0 __put_unused_fd(files, fd);//执行__clear_open_fd(fd, fdt);,进一步执行__clear_bit(fd, fdt->open_fds);,即在open_fds位图中把这个fd位也设置为0;并且还会执行if (fd < files->next_fd)files->next_fd = fd; 至此,进程关联的所有文件描述符中已经不存在这个文件描述符了(根据不存在struct file及其相关dentry,inode,vfsmount了) 释放struct file结构体 fput(filp); 这个函数执行的和sys_read中释放struct file结构体一样的操。 点击(此处)折叠或打开 1. void fput(struct file *file) 2. { 3. if (atomic_long_dec_and_test(&file->f_count)) { 4. struct task_struct *task = current; 5. file_sb_list_del(file); 6. if (unlikely(in_interrupt() || task->flags & PF_KTHREAD)) { 7. unsigned long flags; 8. spin_lock_irqsave(&delayed_fput_lock, flags); 9. list_add(&file->f_u.fu_list, &delayed_fput_list); 10. schedule_work(&delayed_fput_work); 11. spin_unlock_irqrestore(&delayed_fput_lock, flags); 12. return; 13. } 14. init_task_work(&file->f_u.fu_rcuhead, ____fput); 15. task_work_add(task, &file->f_u.fu_rcuhead, true); 16. } 17. } 但是sys_read中是按需调用此fput(filp)函数,sys_read是按需释放(有if判断),详见Linux VFS中read系统调用实现原理 ,这里是直接调用fput(filp) Fput(filp)执行下面的操作 (如果sys_read或sys_write里面已经把这个结构体释放掉了或者struct file结构体的引用计数大于1,sys_close调用fput(filp)函数里面就会什么都不做,这里并不冲突,文章结尾会再次说这个问题) 这里如果当前进程在检查struct file的引用等于1,那么就把这个struct file结构体从超级块的文件链表中也删除掉(但是struct file结构体此时还没有从内存中释放)。 释放操作实际只是注册了一个回调函数,通过下面两行 init_task_work(&file->f_u.fu_rcuhead, ____fput); //____fput是一个实际释放操作的回调函数 task_work_add(task, &file->f_u.fu_rcuhead, true); 其中,____fput函数会释放struct file结构体,以及尝试释放起对应的dentry,mnt(之所以叫尝试是因为调用dput(dentry),dput(mnt),而dput(denty),dput(mnt)会继续检查dentry,mnt是否还在被使用,如果没有任何引用则真正释放所占内存,否则仅减少其引用计数)。 init_task_work中,file->f_u.fu_rcuhead是一个rcu_head节点,内核中 struct callback_head { struct callback_head *next; void (*func)(struct callback_head *head); }; #define rcu_head callback_head 总之,init_task_work把____fput函数进行file->f_u.fu_rcuhead->func=___fput设置 而task_work_add(task, &file->f_u.fu_rcuhead, true);会吧这个rcu_head节点加入task->task_works, 并且会调用set_notify_resume(task)把进程的thread_info的标识里设置上TIF_NOTIFY_RESUME 这样,在进程从内核态返回用户态的时候会调用tracehook_notify_resume把task->task_works链表中的所有注册好的函数都会执行一遍(此时___fput函数就会被调用到了),并且清除TIF_NOTIFY_RESUME标识位 所以,struct file结构体要释放也是在内核返回用户态的时候才执行的,在内核态的时候一直还保留着。 注意,这里__fput中执行的释放操作并没有把进程所拥有的这个文件描述符及其在位图中的占位清空,如果执行了__fput只是这个文件描述符对应的的struct file=NULL了而已,文件描述符还站着呢。这需要后面用户空间再发个sys_close调用才能完成后续清除文件描述符等任务。详见下一篇 注意,这些释放都是内存操作,磁盘上面的文件,inode等并没有释放。 所以,只有调用了sys_close系统调用,进程的所有文件列表中才会把这个文件删除 Sys_read(v),sys_write(v)可能调用了fput(filp)(调用条件如Linux VFS中read系统调用实现原理所述);也可能没有调用fput(filp). 但是sys_read(v),sys_write(v)调用了fput(filp)也不影响close中的这个地方的调用fput(filp),因为fput(filp)本身会先执行if(atomic_long_dec_and_test(&file->f_count)) 条件判断,如果不成立,则什么都不用做。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服