几年前做windows 网络的时候,就一直很好奇,为什么对一个socket既可以使用recv,send等socket API,同时又可以使用writefile和readfile?转到Linux下后,受Everything is file的熏陶,越发对VFS实现产生兴趣,便想结合sockfs对VFS做一个具体的分析。
然而,实践证明,把诸多元素混杂在一起,试图一劳永逸的做法有时候反而会让分析过程更加拖沓和反复,试图使用sockfs来了解整个VFS的实现也是不现实的,因为各个文件系统的使用场景是不相同的。
在明确了上述两点之后,从socket使用场景来入手,会更好一些,这里,只考虑与VFS相关内容,不在考虑诸如accept,listen以及地址域等网络相关的操作。
从文件系统角度来看,socket的几个特殊之处在于:
- socket fd只能通过socket()函数获取,open()无法获取socket的fd
- 虽然socket是一个文件系统,但是它是一个特殊的文件系统,不允许用户mount sockfs
- sockfs 不支持路径查找
由于种种的限制,决定了sockfs的实现比其他文件系统实现要简单的多。我们可以从sockfs的dentry_operations和super_operations中看出来sockfs在偷工减料,尤其是dentry_operations,仅仅实现了一个d_dname.
static const struct dentry_operations sockfs_dentry_operations = {
.d_dname = sockfs_dname,
};
static const struct super_operations sockfs_ops = {
.alloc_inode = sock_alloc_inode,
.destroy_inode = sock_destroy_inode,
.statfs = simple_statfs,
};