您的位置 首页 电子

linux内核中的文件描述符(六)–fd的分配–expand_files

Kernelversion:2614CPUarchitecture:ARM920TAuthor:ce123(http:blogcsdnnetce123)我们先贴出expand_files函数的源码:[

Kernel version:2.6.14

CPU architecture:ARM920T

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

咱们先贴出expand_files函数的源码:

[plain]view plaincopy

print?

  1. intexpand_files(structfiles_struct*files,intnr)
  2. {
  3. interr,expand=0;
  4. structfdtable*fdt;
  5. fdt=files_fdtable(files);
  6. if(nr>=fdt->max_fdset||nr>=fdt->max_fds){//咱们在前面的文章中现已剖析过,初始时max_fdset=1024,max_fds=32
  7. if(fdt->max_fdset>=NR_OPEN||//#defineNR_OPEN(1024*1024)/*Absoluteupperlimitonfdnum*/
  8. fdt->max_fds>=NR_OPEN||nr>=NR_OPEN){
  9. err=-EMFILE;//max_fdset和max_fds都不能大于NR_OPEN,不然回来-EMFILE,即翻开太多的文件
  10. gotoout;
  11. }
  12. expand=1;
  13. if((err=expand_fdtable(files,nr)))//真实进行扩展
  14. gotoout;
  15. }
  16. err=expand;
  17. out:
  18. returnerr;
  19. }

expand_files函数进行一些查看后调用expand_fdtable进行文件描述符表的扩展,下面剖析expand_fdtable函数。

[plain]view plaincopy

print?

  1. staticintexpand_fdtable(structfiles_struct*files,intnr)
  2. __releases(files->file_lock)
  3. __acquires(files->file_lock)
  4. {
  5. interror=0;
  6. structfdtable*fdt;
  7. structfdtable*nfdt=NULL;
  8. spin_unlock(&files->file_lock);
  9. nfdt=alloc_fdtable(nr);//依据nr从头创立一个新的fdtable
  10. if(!nfdt){
  11. error=-ENOMEM;
  12. spin_lock(&files->file_lock);
  13. gotoout;
  14. }
  15. spin_lock(&files->file_lock);
  16. fdt=files_fdtable(files);
  17. /*
  18. *Checkagainsinceanothertaskmayhaveexpandedthe
  19. *fdtablewhilewedroppedthelock
  20. */
  21. if(nr>=fdt->max_fds||nr>=fdt->max_fdset){//nr值有必要大于max_fds和max_fdset值,这儿再次进行查看是避免另一个进程进行了expand
  22. copy_fdtable(nfdt,fdt);//将旧的fdtable中的内容复制至新的fdtable
  23. }else{
  24. /*Somebodyexpandedwhilewedroppedfile_lock*/
  25. spin_unlock(&files->file_lock);
  26. __free_fdtable(nfdt);
  27. spin_lock(&files->file_lock);
  28. gotoout;
  29. }
  30. rcu_assign_pointer(files->fdt,nfdt);//用新的fdtable替换旧的fdtable
  31. free_fdtable(fdt);//开释旧的fdtable
  32. out:
  33. returnerror;
  34. }

咱们再来看一下扩展文件描述符表的要害函数alloc_fdtable,其界说如下:

[plain]view plaincopy

print?

  1. staticstructfdtable*alloc_fdtable(intnr)
  2. {
  3. structfdtable*fdt=NULL;
  4. intnfds=0;
  5. fd_set*new_openset=NULL,*new_execset=NULL;
  6. structfile**new_fds;
  7. fdt=kmalloc(sizeof(*fdt),GFP_KERNEL);
  8. if(!fdt)
  9. gotoout;
  10. memset(fdt,0,sizeof(*fdt));
  11. nfds=__FD_SETSIZE;//#define__FD_SETSIZE1024
  12.     //#definePAGE_SHIFT12
  13.     //#definePAGE_SIZE(1UL<
  14. /*Expandtothemaxineasysteps*/
  15. do{
  16. if(nfds<(PAGE_SIZE*8))//dfds=1024
  17. nfds=PAGE_SIZE*8;
  18. else{
  19. nfds=nfds*2;
  20. if(nfds>NR_OPEN)
  21. nfds=NR_OPEN;
  22. }
  23. }while(nfds<=nr);//第一次expand时,nr应该等于32
  24. new_openset=alloc_fdset(nfds);//分配翻开文件位图
  25. new_execset=alloc_fdset(nfds);
  26. if(!new_openset||!new_execset)
  27. gotoout;
  28. fdt->open_fds=new_openset;
  29. fdt->close_on_exec=new_execset;
  30. fdt->max_fdset=nfds;//更新max_fdset值,此刻这个值为32k
  31. nfds=NR_OPEN_DEFAULT;//nfds=32
  32. /*
  33. *Expandtothemaxineasysteps,andkeepexpandingituntil
  34. *wehaveenoughfortherequestedfdarraysize.
  35. */
  36. do{
  37. #ifNR_OPEN_DEFAULT<256
  38. if(nfds<256)
  39. nfds=256;//nfds=256(32->256->1024)
  40. //无法超越1024,由于在最开端的就进行了查看,一定要小于current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
  41. else
  42. #endif
  43. if(nfds<(PAGE_SIZE/sizeof(structfile*)))
  44. nfds=PAGE_SIZE/sizeof(structfile*);
  45. else{
  46. nfds=nfds*2;
  47. if(nfds>NR_OPEN)
  48. nfds=NR_OPEN;
  49. }
  50. }while(nfds<=nr);
  51. new_fds=alloc_fd_array(nfds);//分配文件描述符数组
  52. if(!new_fds)
  53. gotoout;
  54. fdt->fd=new_fds;
  55. fdt->max_fds=nfds;//更新max_fds
  56. fdt->free_files=NULL;
  57. returnfdt;
  58. out:
  59. if(new_openset)
  60. free_fdset(new_openset,nfds);
  61. if(new_execset)
  62. free_fdset(new_execset,nfds);
  63. kfree(fdt);
  64. returnNULL;
  65. }

alloc_fd_array和alloc_fdset选用kmalloc或许vmalloc进行内存分配。

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部