在 xnu 我们有vnode_t
代表全局文件的实体。
每个进程都可以通过设置新的文件描述符并在 fg_data 下设置 vnode 来访问文件(假设它具有正确的权限)
fp->f_fglob->fg_data = vp;
vnode 包含所有相关操作的基本操作列表,并根据文件的 FS 进行设置。即HFS+ 驱动程序实现这样的向量并相应地设置它的vnode。
int (**v_op)(void *); /* vnode operations vector */
这是一个用于可能在 vnode 上操作的所有操作的函数指针的向量。
此外,我们还有 fileops 结构,它是文件描述符 (fg_global) 的一部分,它描述了这些函数的最小子集:
这是一个典型的定义:
const struct fileops vnops = {
.fo_type = DTYPE_VNODE,
.fo_read = vn_read,
.fo_write = vn_write,
.fo_ioctl = vn_ioctl,
.fo_select = vn_select,
.fo_close = vn_closefile,
.fo_kqfilter = vn_kqfilt_add,
.fo_drain = NULL,
};
我们在这里设置:
fp->f_fglob->fg_ops = &vnops;
我看到在本地文件系统(HFS +)下读取常规文件时,它通过 file_descriptor 而不是 vnode ...
* frame #0: 0xffffff801313c67c kernel`vn_read(fp=0xffffff801f004d98, uio=0xffffff807240be70, flags=0, ctx=0xffffff807240bf10) at vfs_vnops.c:978 [opt]
frame #1: 0xffffff801339cc1a kernel`dofileread [inlined] fo_read(fp=0xffffff801f004d98, uio=0xffffff807240be70, flags=0, ctx=0xffffff807240bf10) at kern_descrip.c:5832 [opt]
frame #2: 0xffffff801339cbff kernel`dofileread(ctx=0xffffff807240bf10, fp=0xffffff801f004d98, bufp=140222138463456, nbyte=282, offset=<unavailable>, flags=<unavailable>, retval=<unavailable>) at sys_generic.c:365 [opt]
frame #3: 0xffffff801339c983 kernel`read_nocancel(p=0xffffff801a597658, uap=0xffffff801a553cc0, retval=<unavailable>) at sys_generic.c:215 [opt]
frame #4: 0xffffff8013425695 kernel`unix_syscall64(state=<unavailable>) at systemcalls.c:376 [opt]
frame #5: 0xffffff8012e9dd46 kernel`hndl_unix_scall64 + 22
我的问题是为什么需要这种对偶性,在哪些情况下操作通过 file_descriptor 向量 (fg_ops) 进行,在哪些情况下操作通过 vnode 向量 (vp->v_op) 进行。
谢谢