您的位置 首页 方案

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

Kernelversion:2614CPUarchitecture:ARM920TAuthor:ce123(http:blogcsdnnetce123)继续上一篇博客的内容,分析另一个文件描述

Kernel version:2.6.14

CPU architecture:ARM920T

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

持续上一篇博客的内容,剖析另一个文件描述符fd的分配函数locate_fd。dup体系调用用于仿制一个文件描述符对应的文件,返回值是个文件描述符。在前面的文章中,咱们现已剖析过了dup的源码(http://blog.csdn.net/ce123/article/details/8444482),在这里咱们深入剖析locate_fd函数,其界说如下:

[plain]view plaincopy

print?

  1. staticintlocate_fd(structfiles_struct*files,
  2. structfile*file,unsignedintorig_start)//从orig_start位开端分配fd
  3. {
  4. unsignedintnewfd;
  5. unsignedintstart;
  6. interror;
  7. structfdtable*fdt;
  8. error=-EINVAL;
  9. if(orig_start>=current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//查看orig_start是大于进程最大能够翻开文件的数量
  10. gotoout;
  11. repeat:
  12. fdt=files_fdtable(files);//文件描述符位图
  13. /*
  14. *Someonemighthaveclosedfdsintherange
  15. *orig_start..fdt->next_fd
  16. */
  17. start=orig_start;
  18. if(startnext_fd)
  19. start=fdt->next_fd;//假如orig_start小于next_fd,那就从next_fd开端分配
  20. newfd=start;
  21. if(startmax_fdset){//max_fdset是描述符问题的位数,下面会具体解说
  22. newfd=find_next_zero_bit(fdt->open_fds->fds_bits,
  23. fdt->max_fdset,start);//分配fd
  24. }
  25. error=-EMFILE;
  26. if(newfd>=current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//进行判别,分配的fd不能大于进程最大能够翻开的文件数量
  27. gotoout;
  28. error=expand_files(files,newfd);//文件描述符表的扩展,这个咱们留在下一篇文章中具体解说
  29. if(error<0)
  30. gotoout;
  31. /*
  32. *Ifweneededtoexpandthefsarraywe
  33. *mighthaveblocked-tryagain.
  34. */
  35. if(error)
  36. gotorepeat;
  37. /*
  38. *Wereacquiredfiles_lock,sowearesafeaslongas
  39. *wereacquirethefdtablepointeranduseitwhileholding
  40. *thelock,noonecanfreeitduringthattime.
  41. */
  42. fdt=files_fdtable(files);
  43. if(start<=fdt->next_fd)
  44. fdt->next_fd=newfd+1;//更新next_fd值
  45. error=newfd;
  46. out:
  47. returnerror;
  48. }

max_fdset值的剖析和rlim_cur差不多,开始的值时从父进程承继过来的。

[plain]view plaincopy

print?

  1. linux/arch/arm/kernel/init_task.c
  2. structtask_structinit_task=INIT_TASK(init_task);
  3. #defineINIT_TASK(tsk)\
  4. {\
  5. .files=&init_files,\
  6. }

init_files的界说如下:

[plain]view plaincopy

print?

  1. staticstructfiles_structinit_files=INIT_FILES;
  2. linux/init_task.h
  3. #defineINIT_FDTABLE\
  4. {\
  5. .max_fds=NR_OPEN_DEFAULT,\
  6. .max_fdset=__FD_SETSIZE,\
  7. .next_fd=0,\
  8. .fd=&init_files.fd_array[0],\
  9. .close_on_exec=&init_files.close_on_exec_init,\
  10. .open_fds=&init_files.open_fds_init,\
  11. .rcu=RCU_HEAD_INIT,\
  12. .free_files=NULL,\
  13. .next=NULL,\
  14. }
  15. #defineNR_OPEN_DEFAULTBITS_PER_LONG
  16. #define__FD_SETSIZE1024
  17. #defineINIT_FILES\
  18. {\
  19. .count=ATOMIC_INIT(1),\
  20. .file_lock=SPIN_LOCK_UNLOCKED,\
  21. .fdt=&init_files.fdtab,\
  22. .fdtab=INIT_FDTABLE,\
  23. .close_on_exec_init={{0,}},\
  24. .open_fds_init={{0,}},\
  25. .fd_array={NULL,}\
  26. }

BITS_PER_LONG是long型数据的字节数,即4*8=3,也就是说max_fds = 32。max_fdset为1024。max_fdset是进程翻开文件描述符位图open_fds的巨细。open_fds是fd_set的指针。

[plain]view plaincopy

print?

  1. typedef__kernel_fd_setfd_set;
  2. #undef__NFDBITS
  3. #define__NFDBITS(8*sizeof(unsignedlong))
  4. #undef__FD_SETSIZE
  5. #define__FD_SETSIZE1024
  6. #undef__FDSET_LONGS
  7. #define__FDSET_LONGS(__FD_SETSIZE/__NFDBITS)
  8. #undef__FDELT
  9. #define__FDELT(d)((d)/__NFDBITS)
  10. #undef__FDMASK
  11. #define__FDMASK(d)(1UL<<((d)%__NFDBITS))
  12. typedefstruct{
  13. unsignedlongfds_bits[__FDSET_LONGS];
  14. }__kernel_fd_set;

fds_bits是一个long型数组,共有32个元素,共有1024bit。

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部