Linux VFS中close系统调用实现原理.doc_第1页
Linux VFS中close系统调用实现原理.doc_第2页
Linux VFS中close系统调用实现原理.doc_第3页
Linux VFS中close系统调用实现原理.doc_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux VFS中close系统调用实现原理目录close系统调用在内核里面的入口函数为sys_close根据用户空间传入的文件描述符fd取出对应的struct file结构体清空进程的文件描述符fd所对应的标准位,如果要关闭的这个的文件描述符对应的fd小于下一次的文件描述符起点,则根系下一次本进程的文件描述符起点为fd释放struct file结构体所以,只有调用了sys_close系统调用,进程的所有文件列表中才会把这个文件删除WORD里面的目录复制过来似乎不能直接用。还是放在这里当主线看吧.close系统调用在内核里面的入口函数为sys_close rootsyslab # 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-fdfd;if (!filp)goto out_unlock;rcu_assign_pointer(fdt-fdfd, 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-filesfd; (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 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中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论