天天看点

TCP/IP源码学习(49)——socket与VFS的关联(3)

作者:[email protected]

博客: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指定的操作。

继续阅读