您的位置 首页 观点

linux内核中的文件描述符(三)–fd的收回

Kernelversion:2614CPUarchitecture:ARM920TAuthor:ce123(http:blogcsdnnetce123)1close函数上图说明了close(fd)的执

Kernel version:2.6.14

CPU architecture:ARM920T

Author:ce123(http://blog.csdn.net/ce123)

1.close函数

上图说明晰close(fd)的履行进程,首要包含两部分:开释文件描述符fd,封闭文件file。

[plain]view plaincopy

print?

  1. //fs/open.c
  2. asmlinkagelongsys_close(unsignedintfd)
  3. {
  4. structfile*filp;
  5. structfiles_struct*files=current->files;//取得当时进程的files结构
  6. structfdtable*fdt;
  7. spin_lock(&files->file_lock);
  8. fdt=files_fdtable(files);//经过进程的翻开文件列表取得文件描述符位图结构
  9. if(fd>=fdt->max_fds)
  10. gotoout_unlock;
  11. filp=fdt->fd[fd];
  12. if(!filp)
  13. gotoout_unlock;
  14. rcu_assign_pointer(fdt->fd[fd],NULL);
  15. FD_CLR(fd,fdt->close_on_exec);
  16. __put_unused_fd(files,fd);//开释文件描述符
  17. spin_unlock(&files->file_lock);
  18. returnfilp_close(filp,files);//封闭文件
  19. out_unlock:
  20. spin_unlock(&files->file_lock);
  21. return-EBADF;
  22. }

2.开释文件描述符__put_unused_fd

[plain]view plaincopy

print?

  1. staticinlinevoid__put_unused_fd(structfiles_struct*files,unsignedintfd)
  2. {
  3. structfdtable*fdt=files_fdtable(files);
  4. __FD_CLR(fd,fdt->open_fds);//铲除位图中的相应符号
  5. if(fdnext_fd)
  6. fdt->next_fd=fd;//假如开释的fd小于next_fd,则next_fd=fd,下次分配从next_fd开端。
  7. //因而开释一个fd后,再翻开或创立一个文件放回的或许仍是刚开释的fd
  8. }

3.封闭文件filp_close

[plain]view plaincopy

print?

  1. intfilp_close(structfile*filp,fl_owner_tid)
  2. {
  3. intretval=0;
  4. if(!file_count(filp)){
  5. printk(KERN_ERR”VFS:Close:filecountis0\n”);
  6. return0;
  7. }
  8. if(filp->f_op&&filp->f_op->flush)
  9. retval=filp->f_op->flush(filp);
  10. dnotify_flush(filp,id);
  11. locks_remove_posix(filp,id);
  12. fput(filp);
  13. returnretval;
  14. }

filp_close函数调用fput,在fput中调用release函数。

[plain]view plaincopy

print?

  1. //fs/file_table.c
  2. voidfastcallfput(structfile*file)
  3. {
  4. if(rcuref_dec_and_test(&file->f_count))
  5. __fput(file);
  6. }
  7. voidfastcall__fput(structfile*file)
  8. {
  9. structdentry*dentry=file->f_dentry;
  10. structvfsmount*mnt=file->f_vfsmnt;
  11. structinode*inode=dentry->d_inode;
  12. might_sleep();
  13. fsnotify_close(file);
  14. /*
  15. *Thefunctioneventpoll_release()shouldbethefirstcalled
  16. *inthefilecleanupchain.
  17. */
  18. eventpoll_release(file);
  19. locks_remove_flock(file);
  20. if(file->f_op&&file->f_op->release)
  21. file->f_op->release(inode,file);//在这里调用release函数。在socket中即socket_close函数
  22. security_file_free(file);
  23. if(unlikely(inode->i_cdev!=NULL))
  24. cdev_put(inode->i_cdev);
  25. fops_put(file->f_op);
  26. if(file->f_mode&FMODE_WRITE)
  27. put_write_access(inode);
  28. file_kill(file);
  29. file->f_dentry=NULL;
  30. file->f_vfsmnt=NULL;
  31. file_free(file);
  32. dput(dentry);
  33. mntput(mnt);
  34. }

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/262415.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部