Linux内核协议栈(附2)内核如何通过file对象找到对应的socket对象?

socket建立后,其他socket 调用都是通过操作得到的文件描述符来操作socket的。

基本上开始都会有这句

sock = sockfd_lookup_light(fd, &err, &fput_needed);//通过fd找到file,进而找到sock

通过文件描述符找到file对象容易理解。但file对象怎么跟socket对象联系起来的呢?

我们进入该函数:

static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
{
	struct file *file;
	struct socket *sock;

	*err = -EBADF;
	file = fget_light(fd, fput_needed);
	if (file) {
		sock = sock_from_file(file, err);
		if (sock)
			return sock;
		fput_light(file, *fput_needed);
	}
	return NULL;
}

发现得到file对象之后,继而调用sock_from_file

static struct socket *sock_from_file(struct file *file, int *err)
{
	if (file->f_op == &socket_file_ops)
		return file->private_data;	/* set in sock_map_fd */

	*err = -ENOTSOCK;
	return NULL;
}

发现直接返回file->private_data;private_data 其实是设计用来保存自定义设备结构体的地址的。自定义结构体的地址被保存在private_data后,可以在read ,write 等驱动函数中被传递和调用自定义设备结构体中的成员,在这里用来保存socket对象的地址。那么socket对象的地址是什么时候赋值给了private_data呢?

我们知道在调用socket函数建立socket时,做了两件事:1.建立socket对象;2.建立file对象并和socket绑定。这个绑定的意思就是将socket对象的地址赋值给file对象的private_data成员。我们看具体的代码。调用流程为:

sys_socket-->sock_map_fd--->sock_attach_fd

看sock_attach_fd函数具体代码:

static int sock_attach_fd(struct socket *sock, struct file *file, int flags)
{
	struct dentry *dentry;
	struct qstr name = { .name = "" };

	dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
	if (unlikely(!dentry))
		return -ENOMEM;

	dentry->d_op = &sockfs_dentry_operations;
	/*
	 * We dont want to push this dentry into global dentry hash table.
	 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
	 * This permits a working /proc/$pid/fd/XXX on sockets
	 */
	dentry->d_flags &= ~DCACHE_UNHASHED;
	d_instantiate(dentry, SOCK_INODE(sock));

	sock->file = file;
	init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
		  &socket_file_ops);
	SOCK_INODE(sock)->i_fop = &socket_file_ops;//
	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
	file->f_pos = 0;
	file->private_data = sock;//set sock as private_date,so that we can get sock by struct file 

	return 0;
}


看到有这句:

file->private_data = sock;//set sock as private_date,so that we can get sock by struct file 

现在估计问题就很明了




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值