日期:2014-05-16 浏览次数:20802 次
linux内核中的文件描述符(四)--fd的分配--get_unused_fd
Kernel version:2.6.14
CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
在linux内核中主要有两个函数涉及到文件描述符的分配:get_unused_fd和locate_fd。本文主要讲解get_unused_fd,将会在下一篇文章中介绍locate_fd。首先给出get_unused_fd的定义(fs/open.c):
int get_unused_fd(void) { struct files_struct * files = current->files;//获得当前进程的打开文件列表files int fd, error; struct fdtable *fdt; error = -EMFILE; spin_lock(&files->file_lock); repeat: fdt = files_fdtable(files);//获得文件描述符位图结构 fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fdset, fdt->next_fd); //find_next_zero_bit函数在文件描述符位图fds_bits中从next_fd位开始搜索下一个(包括next_fd)为0的位,也就是分配一个文教描述符 /* * N.B. For clone tasks sharing a files structure, this test * will limit the total number of files that can be opened. */ if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//检查是否超过当前进程限定的最大可打开文件数 goto out; /* Do we need to expand the fd array or fd set? */ error = expand_files(files, fd);//根据需要扩展fd,稍后我们会详细介绍该函数。返回值<0,错误;返回值>0,扩展后再次进行fd的分配 if (error < 0) goto out; if (error) { /* * If we needed to expand the fs array we * might have blocked - try again. */ error = -EMFILE; goto repeat;//之前进行了扩展操作,重新进行一次空闲fd的分配 } FD_SET(fd, fdt->open_fds);//在open_fds的位图上置位 FD_CLR(fd, fdt->close_on_exec); fdt->next_fd = fd + 1;//next_fd加1 #if 1 /* Sanity check */ if (fdt->fd[fd] != NULL) { printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); fdt->fd[fd] = NULL; } #endif error = fd; out: spin_unlock(&files->file_lock); return error; }
current->signal->rlim[RLIMIT_NOFILE].rlim_cur是一个进程可以打开的最大文件数量。我们首先来看RLIMIT_NOFILE,该值定义如下: