微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > linux内核中的文件描述符(五)--fd的分配--locate_fd

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

时间:11-22 来源:互联网 点击:
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 plaincopyprint?

  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 plaincopyprint?

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

init_files的定义如下:

[plain]view plaincopyprint?

  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 plaincopyprint?

  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。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top