进程中的文件相关参数与文件系统中参数的关联
在应用程序打开一个文件时,系统调用函数sys_open则用于struct file指针变量的创建,inode节点的查找以及与struct file变量的关联等(本小节不介绍文件路径的查找过程,后续会单独说明)。
sys_open函数的调用流程如上所示,首先调用get_unused_fd_flags获取一样未使用的fd。该接口的定义如下
int get_unused_fd_flags(unsigned flags)
{
/*其中rlimit(RLIMIT_NOFILE)用于获取linux内核中所有进程可打开的最大文件数*/
return __alloc_fd(current->files, 0, rlimit(RLIMIT_NOFILE), flags);
}
主要是调用__alloc_fd实现fd的申请,我们分析下这个函数的实现,如下所示该函数所做的工作大致如下:
1.查找一个可用的fd(若没有可用fd,或者查找的fd值大于当前进程可打开的fd,则返回失败)
2.若查找到可用fd,则调用expand_files,确认是否需要扩展fdt
3.程序返回。
/*
* allocate a file descriptor, mark it busy.
*/
int __alloc_fd(struct files_struct *files,
unsigned start, unsigned end, unsigned flags)
{
unsigned int fd;
int error;
struct fdtable *fdt;
/*自旋锁*/
spin_lock(&files->file_lock);
repeat:
/*获取当前进程的ftd指针变量*/
fdt = files_fdtable(files);
/*从start位置开始搜索,针对get_unused_fd_flags,start值为0*/
fd = start;
/*判断是否需要调整fd的值,因在当前进程描述符中,其files->next_fd即为下一个申请的fd值*/
if (fd < files->next_fd)
fd = files->next_fd;
/*判断要申请的fd值是否小于当前进程支持的最大进程数,若小于则,则调用 find_next_zero_bit,查找第一个位数为0位对应的index值。*/
if (fd < fdt->max_fds)
fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, fd);
/*当fd的值大于最大可打开的文件序号时,返回错误*/
/*
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
error = -EMFILE;
if (fd >= end)
goto out;
/*调用expand_files,确认是否需要扩展struct fdtable *fdt指针变量的容量,下面会详细说明*/
error = expand_files(files, fd);
if (error < 0)
goto out;
/*
* If we needed to expand the fs array we
* might have blocked - try again.
*/
if (error)
goto repeat;
/*重新设置files->next_fd,该变量即下一个可用的fd的值,对于fd的值的使用,是递增使用的*/
if (start <= files->next_fd)
files->next_fd = fd + 1;
/*将fdt->open_fds中的第fd位置为1,表示该fd已被使用。*/
__set_open_fd(fd, fdt);
/*根据是否设置O_CLOEXEC*/
if (flags & O_CLOEXEC)
__set_close_on_exec(fd, fdt);
else
__clear_close_on_exec(fd, fdt);
error = fd;
#if 1
/* Sanity check */
if (rcu_dereference_raw(fdt->fd[fd]) != NULL) {
printk(KERN_WARNING "alloc_fd: slot %d not NULL!