gpt4 book ai didi

c - xnu中的vnode和文件描述符,文件操作 vector 存放在哪里

转载 作者:太空宇宙 更新时间:2023-11-03 23:19:34 24 4
gpt4 key购买 nike

在 xnu 中,我们有 vnode_t 实体,它代表全局文件。

每个进程都可以通过设置新的文件描述符并设置fg_data下的vnode来访问文件(假设它有正确的权限)

fp->f_fglob->fg_data = vp;

vnode 包含所有相关操作的基本操作列表,并根据文件的 FS 设置。即 HFS+ 驱动程序实现此类 vector 并相应地设置其 vnode。

int     (**v_op)(void *);       /* vnode operations vector */

这是一个函数指针 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 vector (fg_ops) 进行,哪些情况下操作通过 vnode vector (vp->v_op) 进行。

谢谢

最佳答案

[…] in which cases the operation works through the file_descriptor vector (fg_ops) and which cases the operation works through the vnode vector (vp->v_op).

我将首先回答问题的第二部分:如果您进一步跟踪调用堆栈,并查看 vn_read 函数内部,您会发现它包含以下内容行:

    error = VNOP_READ(vp, uio, ioflag, ctx);

VNOP_READ 函数 (kpi_vfs.c) 依次具有以下内容:

_err = (*vp->v_op[vnop_read_desc.vdesc_offset])(&a);

所以你的问题的答案是,对于你的典型文件,两个表都用于调度操作。

有了这个,

My question is why does this duality needed […]

并非进程可以保存文件描述符的所有内容都在文件系统中表示。例如,管道不一定必须命名。在这种情况下,vnode 没有任何意义。所以在 sys_pipe.c 中,你会看到一个不同的文件操作表:

static const struct fileops pipeops = {
.fo_type = DTYPE_PIPE,
.fo_read = pipe_read,
.fo_write = pipe_write,
.fo_ioctl = pipe_ioctl,
.fo_select = pipe_select,
.fo_close = pipe_close,
.fo_kqfilter = pipe_kqfilter,
.fo_drain = pipe_drain,
};

套接字的类似交易。

文件描述符跟踪允许类文件操作的文件或对象的进程 View 状态。文件中的位置等 - 不同的进程可以打开相同的文件,并且它们必须各自有自己的读/写位置 - 所以 vnode:fileglob 是一对多的关系。

与此同时,使用 vnode 对象来跟踪文件系统中对象以外的事物也没有任何意义。此外,v_op 表是特定于文件系统的,而 vn_read/VNOP_READ 包含适用于文件系统中表示的任何文件的代码。

所以总而言之,它们实际上只是 I/O 堆栈中的不同层。

关于c - xnu中的vnode和文件描述符,文件操作 vector 存放在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44413909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com