博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
本文的copyleft归[email protected]所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
在sock_alloc_file成功返回后,回到函数sock_map_fd中
int sock_map_fd(struct socket *sock, int flags)
{
struct file *newfile;
int fd = sock_alloc_file(sock, &newfile, flags);
if (likely(fd >= 0))
fd_install(fd, newfile);
return fd;
}
这时,sock->file = new_file, 而newfile->private_data = sock,也就是sock已经和file互相关联起来,file的各种文件操作也指向socket的各种操作。但是与fd还没有建立起联系。当sock_alloc_file成功返回时,fd自然大于等于0,进入函数fd_install,这个函数将把文件描述符fd与文件结构file关联。自然通过file,fd与socket也就关联起来。
//这个函数很简单
void fd_install(unsigned int fd, struct file *file)
/* 得到当前进程的文件表 */
struct files_struct *files = current->files;
struct fdtable *fdt;
spin_lock(&files->file_lock);
/* 获得文件描述符表 */
fdt = files_fdtable(files);
BUG_ON(fdt->fd[fd] != NULL);
/* 将新建立的file结构赋给对应的文件描述符为索引的指针 */
rcu_assign_pointer(fdt->fd[fd], file);
spin_unlock(&files->file_lock);
ok。这时已经完成了,socket,fd,和file三者的关联。
简单描述一下三者之间的关联。
每个进程维护了一个打开的文件表,可使用current->files得到,该结构如下:
/*
* Open file table structure
*/
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
struct fdtable *fdt; //文件描述符表
struct fdtable fdtab;//这个我不知道用途是做什么
* written part on a separate cache line in SMP
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd;
struct embedded_fd_set close_on_exec_init;
struct embedded_fd_set open_fds_init;
//实现申请的默认个数的file指针
struct file * fd_array[NR_OPEN_DEFAULT];
};
通过文件描述符,可以得到内部的文件结构体current->files->fdt->fd[socket_fd]——其中socket_fd为传入的文件描述符。由于在创建socket的时候,已经将文件的各种操作函数,绑定到socket的各种操作函数。这样,当使用socket返回的文件描述符,进行各种文件操作,实际上就是对socket执行各种socket指定的操作。