博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP/IP源码学习(48)——socket与VFS的关联(2)
阅读量:6629 次
发布时间:2019-06-25

本文共 2353 字,大约阅读时间需要 7 分钟。

作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
继续昨天的学习。
昨天学习alloc_fd时,还有一个函数expand_files没有进入跟踪。
  1. int expand_files(struct files_struct *files, int nr)
  2. {
  3.     struct fdtable *fdt;
  4.     fdt = files_fdtable(files);
  5.     /*
  6.      * N.B. For clone tasks sharing a files structure, this test
  7.      * will limit the total number of files that can be opened.
  8.      */
  9.     /* 检查是否超过当前进程限定的最大可打开文件数 */
  10.     if (nr >= rlimit(RLIMIT_NOFILE))
  11.         return -EMFILE;
  12.     /* Do we need to expand? */
  13.     /* 
  14.     如果nr小于max_fds,即目前的文件表的个数已经超过了nr, 所以无需扩展。
  15.     这也说明,文件表只会增大,不会减小。
  16.     */
  17.     if (nr fdt->max_fds)
  18.         return 0;
  19.     /* Can we expand? */
  20.     /* 
  21.     检查是否超过了系统限定的最大可打开文件数
  22.     注意前面的检查为当前进程的打开文件数,此处的检查为系统可打开的文件数——所有进程
  23.     */
  24.     if (nr >= sysctl_nr_open)
  25.         return -EMFILE;
  26.     /* All good, so we try */
  27.     /* 真正去做expand*/
  28.     return expand_fdtable(files, nr);
  29. }
进入expand_fdtable
  1. static int expand_fdtable(struct files_struct *files, int nr)
  2.     __releases(files->file_lock)
  3.     __acquires(files->file_lock)
  4. {
  5.     struct fdtable *new_fdt, *cur_fdt;
  6.     spin_unlock(&files->file_lock);
  7.     /* 申请新的文件表 */
  8.     new_fdt = alloc_fdtable(nr);
  9.     spin_lock(&files->file_lock);
  10.     if (!new_fdt)
  11.         return -ENOMEM;
  12.     /*
  13.      * extremely unlikely race - sysctl_nr_open decreased between the check in
  14.      * caller and alloc_fdtable(). Cheaper to catch it here...
  15.      */
  16.     /* 如注释所示,由于竞争,有可能在申请nr个数的新文件表时,修改了sysctl_nr_open,导致新的文件表个数     小于我们所需要的。所以,这里需要对new_fdt->max_fds和nr进行判断。如果小于nr,那么expand失败 */
  17.     if (unlikely(new_fdt->max_fds = nr)) {
  18.         __free_fdtable(new_fdt);
  19.         return -EMFILE;
  20.     }
  21.     /*
  22.      * Check again since another task may have expanded the fd table while
  23.      * we dropped the lock
  24.      */
  25.     cur_fdt = files_fdtable(files);
  26.     /* 如注释所示,有可能另外一个进程已经扩展了文件表,所以这里再次判断 */
  27.     if (nr >= cur_fdt->max_fds) {
  28.         /* 复制文件表 */
  29.         /* Continue as planned */
  30.         copy_fdtable(new_fdt, cur_fdt);
  31.         rcu_assign_pointer(files->fdt, new_fdt);
  32.         /* 
  33.         对于文件表结构struct files_struct,其成员变量fd_array为一个大小为NR_OPEN_DEFAULT的数             组。这是一种常用的技巧。一般来说,进程的打开的文件不会太多,所以可以直接使用一个比较小的数组,这         样可以提高效率避免二次分配,同时由于数组较小,并不会太浪费空间。当文件个数超过数组大小的时候,再         重新申请内存。*/
  34.         if (cur_fdt->max_fds > NR_OPEN_DEFAULT)
  35.             free_fdtable(cur_fdt);
  36.     } else {
  37.         /* Somebody else expanded, so undo our attempt */
  38.         __free_fdtable(new_fdt);
  39.     }
  40.     return 1;
  41. }
expand_files结束之后,alloc_fd也学习完了,即宏get_unused_fd_flags也就结束了,那么我们就再次回到了函数sock_alloc_file,继续学习其调用的其它函数。
你可能感兴趣的文章
Erase arr(清空VBA数组)
查看>>
在 Amazon Linux 或 Amazon Linux 2 上安装 SSM 代理
查看>>
FZU-2090 旅行社的烦恼(floyd求最小环)
查看>>
HTTP协议 (七) Cookie
查看>>
makefile
查看>>
深入理解linux内核自旋锁
查看>>
【转载】7 Steps for Calculating the Largest Lyapunov Exponent of Continuous Systems
查看>>
如何判断一个C++对象是否在堆栈上
查看>>
Sessions, Window Stations and Desktops
查看>>
GCC的符号可见性——解决多个库同名符号冲突问题
查看>>
关于nil和 null和NSNull的区别及相关问题
查看>>
福大软工1816 · 第一次作业 - 准备之——自我介绍
查看>>
fiddler(三)、会话框添加显示请求方法栏
查看>>
链表(list)——C++实现
查看>>
JavaScript遍历对象-总结一
查看>>
VBA ado 把CSV文件当做数据源进行 查询操作
查看>>
JavaBean规范
查看>>
子程序和程序包-1
查看>>
django -- 为model 指定数据库名
查看>>
mysql各种日志对应的配置项
查看>>