Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Feb 2004 11:08:38 +0200
From:      Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To:        freebsd-hackers@freebsd.org
Subject:   Changing v_op for vnode on the fly
Message-ID:  <20040213090838.GA221@pm514-9.comsys.ntu-kpi.kiev.ua>

next in thread | raw e-mail | index | archive | help
Hello all,

I want to control in a KLD module when any process make any
VOPs, which can change the content of some file.  For this I change
v_op field in the needed vnode to my vnodeop_p, currently my VOPs
print some debug information and call original VOPs for the vnode.

I can't simply wrap syscall entries for a process to control write()
and read() syscalls, because it is unknown in my task which process
can access a file and processes can mmap a file and modify or read it
directly in their memory.

Is it enough to get exclusive lock on vnode, before changing
v_op pointer?  Here is my code:

	vn_lock(cvp->vp, LK_EXCLUSIVE | LK_RETRY, p);

	if (flag > 0)
		cvp->vp->v_op = catch_vnode_vnodeop_p;	/* My vnodeop_p. */
	else
		cvp->vp->v_op = cvp->vnodeop_p;		/* Original v_op. */

	VOP_UNLOCK(cvp->vp, 0, p);

I made some tests and see that most of VOP_xxx require lock (shared
or exclusive) on vnode, as well this is documented in the manual pages.

Another my question.

Below I include one of my tests on FreeBSD 4.8: ">>>..." means start of the
operation, "<<<" means end of the operation, "mod:..." are messages from
the KLD module.

According to documentation "VOP_GETATTR expects the vnode to be locked
on entry and will leave the vnode locked on return".  In my test a file
is mmap'ed as MAP_SHARED with PROT_WRITE and one char is put in mmap'ed
memory.

Why mmap() system call (vm/vm_mmap.c:mmap() and vm/vm_mmap.c:vm_mmap())
doesn't lock the vnode before VOP_GETATTR?

[simon@comp1 test1]% ./test1
mod: fd = 3, flag = catch -> vnode 0xc89ce0c0
mod: vnode_unlock 0xc89ce0c0 ()
>>> mmap file
mod: vnode_getvobject 0xc89ce0c0
mod: vnode_getattr 0xc89ce0c0
mod: vnode_getattr 0xc89ce0c0
<<<
>>> put char to mmap'ed file
mod: vnode_lock 0xc89ce0c0 (LK_SHARED | LK_CANRECURSE | LK_NOPAUSE | LK_INTERLOC
K | LK_RETRY)
mod: vnode_bmap 0xc89ce0c0
mod: vnode_getpages 0xc89ce0c0
mod: vnode_unlock 0xc89ce0c0 ( | LK_INTERLOCK)
<<<
mod: vnode_islocked 0xc89ce0c0
mod: vnode_lock 0xc89ce0c0 (LK_EXCLUSIVE | LK_NOPAUSE | LK_INTERLOCK | LK_RETRY
| LK_NOOBJ)
mod: vnode_getvobject 0xc89ce0c0
mod: vnode_putpages 0xc89ce0c0
mod: vnode_write 0xc89ce0c0
mod: vnode_balloc 0xc89ce0c0
mod: vnode_unlock 0xc89ce0c0 ( | LK_INTERLOCK)
mod: vnode_lock 0xc89ce0c0 (LK_EXCLUSIVE | LK_NOWAIT | LK_NOPAUSE | LK_INTERLOCK
)
mod: vnode_fsync 0xc89ce0c0
mod: vnode_bwrite 0xc89ce0c0
mod: vnode_getvobject 0xc89ce0c0
mod: vnode_strategy 0xc89ce0c0
mod: vnode_unlock 0xc89ce0c0 ()
mod: vnode_getvobject 0xc89ce0c0
^Cmod: fd = 3, flag = restore -> vnode 0xc89ce0c0
mod: vnode_lock 0xc89ce0c0 (LK_EXCLUSIVE | LK_NOPAUSE | LK_INTERLOCK | LK_RETRY)
 
[simon@comp1 test1]%



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040213090838.GA221>