作者:gfree.wind@gmail.com
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
本文的copyleft归gfree.wind@gmail.com所有,使用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指定的操作。