新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > linux內(nèi)核中的文件描述符(五)--fd的分配--locate_fd

linux內(nèi)核中的文件描述符(五)--fd的分配--locate_fd

作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
Kernel version:2.6.14

CPU architecture:ARM920T

本文引用地址:http://m.butianyuan.cn/article/201611/320001.htm

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

繼續(xù)上一篇博客的內(nèi)容,分析另一個文件描述符fd的分配函數(shù)locate_fd。dup系統(tǒng)調(diào)用用于復(fù)制一個文件描述符對應(yīng)的文件,返回值是個文件描述符。在前面的文章中,我們已經(jīng)分析過了dup的源碼(http://blog.csdn.net/ce123/article/details/8444482),在這里我們深入分析locate_fd函數(shù),其定義如下:

[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是大于進(jìn)程最大可以打開文件的數(shù)量
  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是描述符問題的位數(shù),下面會具體講解
  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)//進(jìn)行判斷,分配的fd不能大于進(jìn)程最大可以打開的文件數(shù)量
  27. gotoout;
  28. error=expand_files(files,newfd);//文件描述符表的擴(kuò)展,這個我們留在下一篇文章中詳細(xì)講解
  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差不多,最初的值時從父進(jìn)程繼承過來的。

[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. ...
  6. .files=&init_files,
  7. ...
  8. }
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型數(shù)據(jù)的字節(jié)數(shù),即4*8=3,也就是說max_fds = 32。max_fdset為1024。max_fdset是進(jìn)程打開文件描述符位圖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型數(shù)組,共有32個元素,共有1024bit。


評論


技術(shù)專區(qū)

關(guān)閉