init_sysent.c 初始化:
struct sysent { /* system call table */
int sy_narg; /* number of arguments */
sy_call_t *sy_call; /* implementing function */
au_event_t sy_auevent; /* audit event associated with syscall */
systrace_args_func_t sy_systrace_args_func;
/* optional argument conversion function. */
u_int32_t sy_entry; /* DTrace entry ID for systrace. */
u_int32_t sy_return; /* DTrace return ID for systrace. */
u_int32_t sy_flags; /* General flags for system calls. */
};
typedef int sy_call_t(struct thread *, void *);
///////////////////// sys_generic.c:
int write(struct thread *, struct write_args *);
write(td, uap)
=> kern_writev
=> dofilewrite
=>fo_write :
return ((*fp->f_ops->fo_write)(fp, uio, active_cred, flags, td));
//////////////////// vfs_vnops.c:
struct fileops vnops = {
.fo_read = vn_read,
.fo_write = vn_write,
////////
vn_write=>VOP_WRITE
///////
sys/kern/vnode_if.src 实现 VOP_WRITE
struct vop_write_args {
struct vop_generic_args a_gen;
struct vnode *a_vp;
struct uio *a_uio;
int a_ioflag;
struct ucred *a_cred;
};
static __inline int VOP_WRITE(
struct vnode *vp,
struct uio *uio,
int ioflag,
struct ucred *cred)
{
struct vop_write_args a;
a.a_gen.a_desc = &vop_write_desc;
a.a_vp = vp;
a.a_uio = uio;
a.a_ioflag = ioflag;
a.a_cred = cred;
return (
VOP_WRITE_APV(vp->v_op, &a));
}
/////////////////// 对proc类文件系统
VOP_WRITE =? pfs_write
pseudofs_vnops.c:
.vop_write = pfs_write,
//////////////////////////////////////////////
//////////////////////////////////////////////
int
VOP_WRITE_AP(struct vop_write_args *a)
{
return(VOP_WRITE_APV(a->a_vp->v_op, a));
}
int
VOP_WRITE_APV(struct vop_vector *vop, struct vop_write_args *a)
{
int rc;
VNASSERT(a->a_gen.a_desc == &vop_write_desc, a->a_vp,
("Wrong a_desc in vop_write(%p, %p)", a->a_vp, a));
while(vop != NULL && \
vop->vop_write == NULL && vop->vop_bypass == NULL)
vop = vop->vop_default;
VNASSERT(vop != NULL, a->a_vp, ("No vop_write(%p, %p)", a->a_vp, a));
SDT_PROBE(vfs, vop, vop_write, entry, a->a_vp, a, 0, 0, 0);
ASSERT_VI_UNLOCKED(a->a_vp, "VOP_WRITE");
ASSERT_VOP_LOCKED(a->a_vp, "VOP_WRITE");
VOP_WRITE_PRE(a);
if (vop->vop_write != NULL)
rc = vop->vop_write(a);
else
rc = vop->vop_bypass(&a->a_gen);
CTR4(KTR_VOP,
"VOP_WRITE(vp 0x%lX, uio 0x%lX, ioflag %ld, cred 0x%lX)",
a->a_vp, a->a_uio, a->a_ioflag, a->a_cred);
SDT_PROBE(vfs, vop, vop_write, return, a->a_vp, a, rc, 0, 0);
if (rc == 0) {
ASSERT_VI_UNLOCKED(a->a_vp, "VOP_WRITE");
ASSERT_VOP_LOCKED(a->a_vp, "VOP_WRITE");
} else {
ASSERT_VI_UNLOCKED(a->a_vp, "VOP_WRITE");
ASSERT_VOP_LOCKED(a->a_vp, "VOP_WRITE");
}
VOP_WRITE_POST(a, rc);
return (rc);
}
vnode_if.zip