[src] cvs commit: src/sys/fs/tmpfs tmpfs.h tmpfs_subr.c
tmpfs_vfsops.c tmpfs_vnops.c
Kostik Belousov
kostikbel at gmail.com
Fri Aug 10 02:26:26 PDT 2007
On Fri, Aug 10, 2007 at 05:24:54AM +0000, Xin LI wrote:
> delphij 2007-08-10 05:24:49 UTC
>
> FreeBSD src repository
>
> Modified files:
> sys/fs/tmpfs tmpfs.h tmpfs_subr.c tmpfs_vfsops.c
> tmpfs_vnops.c
> Log:
> MFp4:
>
> - Respect cnflag and don't lock vnode always as LK_EXCLUSIVE [1]
> - Properly lock around tn_vnode to avoid NULL deference
> - Be more careful handling vnodes (*)
>
> (*) This is a WIP
> [1] by pjd via howardsu
>
> Thanks kib@ for his valuable VFS related comments.
>
> Tested with: fsx, fstest, tmpfs regression test set
> Found by: pho's stress2 suite
> Approved by: re (tmpfs blanket)
>
> Revision Changes Path
> 1.10 +2 -2 src/sys/fs/tmpfs/tmpfs.h
> 1.11 +28 -19 src/sys/fs/tmpfs/tmpfs_subr.c
> 1.9 +5 -2 src/sys/fs/tmpfs/tmpfs_vfsops.c
> 1.9 +34 -13 src/sys/fs/tmpfs/tmpfs_vnops.c
> Index: src/sys/fs/tmpfs/tmpfs_subr.c
> diff -u src/sys/fs/tmpfs/tmpfs_subr.c:1.10 src/sys/fs/tmpfs/tmpfs_subr.c:1.11
> --- src/sys/fs/tmpfs/tmpfs_subr.c:1.10 Fri Aug 3 06:24:31 2007
> +++ src/sys/fs/tmpfs/tmpfs_subr.c Fri Aug 10 05:24:49 2007
> @@ -302,15 +308,20 @@
> * Returns zero on success or an appropriate error code on failure.
> */
> int
> -tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, struct vnode **vpp,
> - struct thread *td)
> +tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag,
> + struct vnode **vpp, struct thread *td)
> {
> int error;
> struct vnode *vp;
>
> loop:
> + TMPFS_NODE_LOCK(node);
> if ((vp = node->tn_vnode) != NULL) {
> - error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
> + VI_LOCK(vp);
> + TMPFS_NODE_UNLOCK(node);
> + vholdl(vp);
> + error = vget(vp, lkflag | LK_INTERLOCK | LK_RETRY, td);
> + vdrop(vp);
> if (error)
> return error;
LK_RETRY prohibits the vget() and vn_lock() to return error.
> Index: src/sys/fs/tmpfs/tmpfs_vnops.c
> diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.8 src/sys/fs/tmpfs/tmpfs_vnops.c:1.9
> --- src/sys/fs/tmpfs/tmpfs_vnops.c:1.8 Thu Jul 19 03:34:50 2007
> +++ src/sys/fs/tmpfs/tmpfs_vnops.c Fri Aug 10 05:24:49 2007
> @@ -95,12 +95,20 @@
> !(cnp->cn_flags & ISDOTDOT)));
>
> if (cnp->cn_flags & ISDOTDOT) {
> - VOP_UNLOCK(dvp, 0, td);
> + int ltype = 0;
>
> + ltype = VOP_ISLOCKED(dvp, td);
> + vholdl(dvp);
vholdl() assumes that vnode interlock is locked, not vnode itself. You shall
use vhold() when not holding vnode interlock.
Later, you use dvp->v_mount, that could change to NULL once you dropped the
dvp lock. Moreover, filesystem may be unmounted after you dropped vnode
lock. UFS has the same problem.
> + VOP_UNLOCK(dvp, 0, td);
> /* Allocate a new vnode on the matching entry. */
> - error = tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent, vpp, td);
> + error = tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent,
> + cnp->cn_lkflags, vpp, td);
>
> - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
> + vn_lock(dvp, ltype | LK_RETRY, td);
> + if (ltype & LK_INTERLOCK)
> + vdropl(dvp);
> + else
> + vdrop(dvp);
ltype cannot contain LK_INTERLOCK flag. Moreover, vn_lock() always returns
with interlock being dropped. You shall simply vdrop(dvp) there.
>
> dnode->tn_dir.tn_parent->tn_lookup_dirent = NULL;
> } else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/cvs-src/attachments/20070810/a4e9117d/attachment.pgp
More information about the cvs-src
mailing list