svn commit: r186111 - releng/7.1/sys/fs/unionfs

Daichi GOTO daichi at FreeBSD.org
Mon Dec 15 03:58:56 UTC 2008


Author: daichi
Date: Mon Dec 15 03:58:55 2008
New Revision: 186111
URL: http://svn.freebsd.org/changeset/base/186111

Log:
  MFC r185284, r185283
  
  PR:             118346
  Submitted by:   Masanori OZAWA <ozawa at ongs.co.jp>, trasz
  Discussed at:   devsummit Strassburg, EuroBSDCon2008
  Discussed with: rwatson, gnn, hrs
  Approved by:    re (gnn)

Modified:
  releng/7.1/sys/fs/unionfs/union.h
  releng/7.1/sys/fs/unionfs/union_subr.c
  releng/7.1/sys/fs/unionfs/union_vfsops.c
  releng/7.1/sys/fs/unionfs/union_vnops.c

Modified: releng/7.1/sys/fs/unionfs/union.h
==============================================================================
--- releng/7.1/sys/fs/unionfs/union.h	Mon Dec 15 03:56:54 2008	(r186110)
+++ releng/7.1/sys/fs/unionfs/union.h	Mon Dec 15 03:58:55 2008	(r186111)
@@ -117,6 +117,7 @@ void unionfs_create_uppervattr_core(stru
 int unionfs_create_uppervattr(struct unionfs_mount *ump, struct vnode *lvp, struct vattr *uva, struct ucred *cred, struct thread *td);
 int unionfs_mkshadowdir(struct unionfs_mount *ump, struct vnode *duvp, struct unionfs_node *unp, struct componentname *cnp, struct thread *td);
 int unionfs_mkwhiteout(struct vnode *dvp, struct componentname *cnp, struct thread *td, char *path);
+int unionfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct componentname *cn, struct thread *td, char *path, int pathlen, u_long nameiop);
 int unionfs_relookup_for_create(struct vnode *dvp, struct componentname *cnp, struct thread *td);
 int unionfs_relookup_for_delete(struct vnode *dvp, struct componentname *cnp, struct thread *td);
 int unionfs_relookup_for_rename(struct vnode *dvp, struct componentname *cnp, struct thread *td);

Modified: releng/7.1/sys/fs/unionfs/union_subr.c
==============================================================================
--- releng/7.1/sys/fs/unionfs/union_subr.c	Mon Dec 15 03:56:54 2008	(r186110)
+++ releng/7.1/sys/fs/unionfs/union_subr.c	Mon Dec 15 03:58:55 2008	(r186111)
@@ -103,10 +103,10 @@ unionfs_get_hashhead(struct vnode *dvp, 
 }
 
 /*
- * Get the cached vnode. (only VDIR)
+ * Get the cached vnode.
  */
 static struct vnode *
-unionfs_get_cached_vdir(struct vnode *uvp, struct vnode *lvp,
+unionfs_get_cached_vnode(struct vnode *uvp, struct vnode *lvp,
 			struct vnode *dvp, char *path)
 {
 	struct unionfs_node_hashhead *hd;
@@ -114,9 +114,9 @@ unionfs_get_cached_vdir(struct vnode *uv
 	struct vnode   *vp;
 
 	KASSERT((uvp == NULLVP || uvp->v_type == VDIR),
-	        ("unionfs_get_cached_vdir: v_type != VDIR"));
+	    ("unionfs_get_cached_vnode: v_type != VDIR"));
 	KASSERT((lvp == NULLVP || lvp->v_type == VDIR),
-	        ("unionfs_get_cached_vdir: v_type != VDIR"));
+	    ("unionfs_get_cached_vnode: v_type != VDIR"));
 
 	VI_LOCK(dvp);
 	hd = unionfs_get_hashhead(dvp, path);
@@ -140,10 +140,10 @@ unionfs_get_cached_vdir(struct vnode *uv
 }
 
 /*
- * Add the new vnode into cache. (only VDIR)
+ * Add the new vnode into cache.
  */
 static struct vnode *
-unionfs_ins_cached_vdir(struct unionfs_node *uncp,
+unionfs_ins_cached_vnode(struct unionfs_node *uncp,
 			struct vnode *dvp, char *path)
 {
 	struct unionfs_node_hashhead *hd;
@@ -151,9 +151,9 @@ unionfs_ins_cached_vdir(struct unionfs_n
 	struct vnode   *vp;
 
 	KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR),
-	        ("unionfs_ins_cached_vdir: v_type != VDIR"));
+	    ("unionfs_ins_cached_vnode: v_type != VDIR"));
 	KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR),
-	        ("unionfs_ins_cached_vdir: v_type != VDIR"));
+	    ("unionfs_ins_cached_vnode: v_type != VDIR"));
 
 	VI_LOCK(dvp);
 	hd = unionfs_get_hashhead(dvp, path);
@@ -180,16 +180,16 @@ unionfs_ins_cached_vdir(struct unionfs_n
 }
 
 /*
- * Remove the vnode. (only VDIR)
+ * Remove the vnode.
  */
 static void
-unionfs_rem_cached_vdir(struct unionfs_node *unp, struct vnode *dvp)
+unionfs_rem_cached_vnode(struct unionfs_node *unp, struct vnode *dvp)
 {
-	KASSERT((unp != NULL), ("unionfs_rem_cached_vdir: null node"));
+	KASSERT((unp != NULL), ("unionfs_rem_cached_vnode: null node"));
 	KASSERT((dvp != NULLVP),
-	    ("unionfs_rem_cached_vdir: null parent vnode"));
+	    ("unionfs_rem_cached_vnode: null parent vnode"));
 	KASSERT((unp->un_hash.le_prev != NULL),
-	    ("unionfs_rem_cached_vdir: null hash"));
+	    ("unionfs_rem_cached_vnode: null hash"));
 
 	VI_LOCK(dvp);
 	LIST_REMOVE(unp, un_hash);
@@ -233,9 +233,9 @@ unionfs_nodeget(struct mount *mp, struct
 	if (cnp && !(cnp->cn_flags & ISLASTCN))
 		path = NULL;
 
-	/* check the vdir cache */
+	/* check the cache */
 	if (path != NULL && dvp != NULLVP && vt == VDIR) {
-		vp = unionfs_get_cached_vdir(uppervp, lowervp, dvp, path);
+		vp = unionfs_get_cached_vnode(uppervp, lowervp, dvp, path);
 		if (vp != NULLVP) {
 			vref(vp);
 			*vpp = vp;
@@ -255,17 +255,17 @@ unionfs_nodeget(struct mount *mp, struct
 	 * might cause a bogus v_data pointer to get dereferenced elsewhere
 	 * if MALLOC should block.
 	 */
-	MALLOC(unp, struct unionfs_node *, sizeof(struct unionfs_node),
+	unp = malloc(sizeof(struct unionfs_node),
 	    M_UNIONFSNODE, M_WAITOK | M_ZERO);
 
 	error = getnewvnode("unionfs", mp, &unionfs_vnodeops, &vp);
 	if (error != 0) {
-		FREE(unp, M_UNIONFSNODE);
+		free(unp, M_UNIONFSNODE);
 		return (error);
 	}
 	error = insmntque(vp, mp);	/* XXX: Too early for mpsafe fs */
 	if (error != 0) {
-		FREE(unp, M_UNIONFSNODE);
+		free(unp, M_UNIONFSNODE);
 		return (error);
 	}
 	if (dvp != NULLVP)
@@ -302,7 +302,7 @@ unionfs_nodeget(struct mount *mp, struct
 		vp->v_vflag |= VV_ROOT;
 
 	if (path != NULL && dvp != NULLVP && vt == VDIR)
-		*vpp = unionfs_ins_cached_vdir(unp, dvp, path);
+		*vpp = unionfs_ins_cached_vnode(unp, dvp, path);
 	if ((*vpp) != NULLVP) {
 		if (dvp != NULLVP)
 			vrele(dvp);
@@ -363,7 +363,7 @@ unionfs_noderem(struct vnode *vp, struct
 	vp->v_object = NULL;
 
 	if (dvp != NULLVP && unp->un_hash.le_prev != NULL)
-		unionfs_rem_cached_vdir(unp, dvp);
+		unionfs_rem_cached_vnode(unp, dvp);
 
 	if (lvp != NULLVP) {
 		vfslocked = VFS_LOCK_GIANT(lvp->v_mount);
@@ -402,7 +402,7 @@ unionfs_noderem(struct vnode *vp, struct
 		LIST_REMOVE(unsp, uns_list);
 		free(unsp, M_TEMP);
 	}
-	FREE(unp, M_UNIONFSNODE);
+	free(unp, M_UNIONFSNODE);
 }
 
 /*
@@ -427,8 +427,8 @@ unionfs_get_node_status(struct unionfs_n
 	}
 
 	/* create a new unionfs node status */
-	MALLOC(unsp, struct unionfs_node_status *,
-	    sizeof(struct unionfs_node_status), M_TEMP, M_WAITOK | M_ZERO);
+	unsp = malloc(sizeof(struct unionfs_node_status),
+	    M_TEMP, M_WAITOK | M_ZERO);
 
 	unsp->uns_pid = pid;
 	LIST_INSERT_HEAD(&(unp->un_unshead), unsp, uns_list);
@@ -527,7 +527,7 @@ unionfs_create_uppervattr(struct unionfs
  * locked, referenced vnode. If *vpp == dvp then remember that only one
  * LK_EXCLUSIVE lock is held.
  */
-static int
+int
 unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
 		 struct componentname *cnp, struct componentname *cn,
 		 struct thread *td, char *path, int pathlen, u_long nameiop)
@@ -718,6 +718,7 @@ unionfs_node_update(struct unionfs_node 
 
 	vp = UNIONFSTOV(unp);
 	lvp = unp->un_lowervp;
+	ASSERT_VOP_ELOCKED(lvp, "unionfs_node_update");
 	dvp = unp->un_dvp;
 
 	/*

Modified: releng/7.1/sys/fs/unionfs/union_vfsops.c
==============================================================================
--- releng/7.1/sys/fs/unionfs/union_vfsops.c	Mon Dec 15 03:56:54 2008	(r186110)
+++ releng/7.1/sys/fs/unionfs/union_vfsops.c	Mon Dec 15 03:58:55 2008	(r186111)
@@ -66,43 +66,6 @@ static vfs_extattrctl_t	unionfs_extattrc
 static struct vfsops unionfs_vfsops;
 
 /*
- * Exchange from userland file mode to vmode.
- */
-static u_short 
-mode2vmode(mode_t mode)
-{
-	u_short		ret;
-
-	ret = 0;
-
-	/* other */
-	if (mode & S_IXOTH)
-		ret |= VEXEC >> 6;
-	if (mode & S_IWOTH)
-		ret |= VWRITE >> 6;
-	if (mode & S_IROTH)
-		ret |= VREAD >> 6;
-
-	/* group */
-	if (mode & S_IXGRP)
-		ret |= VEXEC >> 3;
-	if (mode & S_IWGRP)
-		ret |= VWRITE >> 3;
-	if (mode & S_IRGRP)
-		ret |= VREAD >> 3;
-
-	/* owner */
-	if (mode & S_IXUSR)
-		ret |= VEXEC;
-	if (mode & S_IWUSR)
-		ret |= VWRITE;
-	if (mode & S_IRUSR)
-		ret |= VREAD;
-
-	return (ret);
-}
-
-/*
  * Mount unionfs layer.
  */
 static int
@@ -173,7 +136,7 @@ unionfs_domount(struct mount *mp, struct
 			vfs_mount_error(mp, "Invalid udir");
 			return (EINVAL);
 		}
-		udir = mode2vmode(udir);
+		udir &= S_IRWXU | S_IRWXG | S_IRWXO;
 	}
 	if (vfs_getopt(mp->mnt_optnew, "ufile", (void **)&tmp, NULL) == 0) {
 		if (tmp != NULL)
@@ -182,7 +145,7 @@ unionfs_domount(struct mount *mp, struct
 			vfs_mount_error(mp, "Invalid ufile");
 			return (EINVAL);
 		}
-		ufile = mode2vmode(ufile);
+		ufile &= S_IRWXU | S_IRWXG | S_IRWXO;
 	}
 	/* check umask, uid and gid */
 	if (udir == 0 && ufile != 0)
@@ -267,7 +230,7 @@ unionfs_domount(struct mount *mp, struct
 	/*
 	 * Find upper node
 	 */
-	NDINIT(ndp, LOOKUP, FOLLOW | WANTPARENT | LOCKLEAF, UIO_SYSSPACE, target, td);
+	NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, target, td);
 	if ((error = namei(ndp)))
 		return (error);
 
@@ -277,9 +240,6 @@ unionfs_domount(struct mount *mp, struct
 	lowerrootvp = mp->mnt_vnodecovered;
 	upperrootvp = ndp->ni_vp;
 
-	vrele(ndp->ni_dvp);
-	ndp->ni_dvp = NULLVP;
-
 	/* create unionfs_mount */
 	ump = (struct unionfs_mount *)malloc(sizeof(struct unionfs_mount),
 	    M_UNIONFSMNT, M_WAITOK | M_ZERO);
@@ -309,7 +269,7 @@ unionfs_domount(struct mount *mp, struct
 	    (upperrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE))
 		mp->mnt_kern_flag |= MNTK_MPSAFE;
 	MNT_IUNLOCK(mp);
-	mp->mnt_data = (qaddr_t)ump;
+	mp->mnt_data = ump;
 
 	/*
 	 * Copy upper layer's RDONLY flag.

Modified: releng/7.1/sys/fs/unionfs/union_vnops.c
==============================================================================
--- releng/7.1/sys/fs/unionfs/union_vnops.c	Mon Dec 15 03:56:54 2008	(r186110)
+++ releng/7.1/sys/fs/unionfs/union_vnops.c	Mon Dec 15 03:58:55 2008	(r186111)
@@ -71,6 +71,10 @@
 #define UNIONFS_INTERNAL_DEBUG(msg, args...)
 #endif
 
+#define KASSERT_UNIONFS_VNODE(vp) \
+	KASSERT(((vp)->v_op == &unionfs_vnodeops), \
+	    ("unionfs: it is not unionfs-vnode"))
+
 /* lockmgr lock <-> reverse table */
 struct lk_lr_table {
 	int	lock;
@@ -307,8 +311,27 @@ unionfs_lookup(struct vop_cachedlookup_a
 			error = lerror;
 		if (error != 0)
 			goto unionfs_lookup_out;
-		error = unionfs_nodeget(dvp->v_mount, uvp, lvp, dvp, &vp,
-		    cnp, td);
+		/*
+		 * get socket vnode.
+		 */
+		if (uvp != NULLVP && uvp->v_type == VSOCK) {
+			vp = uvp;
+			vref(vp);
+			if (cnp->cn_lkflags & LK_TYPE_MASK)
+				vn_lock(vp, cnp->cn_lkflags | LK_RETRY, td);
+		}
+		else if (lvp != NULLVP && lvp->v_type == VSOCK) {
+			vp = lvp;
+			vref(vp);
+			if (cnp->cn_lkflags & LK_TYPE_MASK)
+				vn_lock(vp, cnp->cn_lkflags | LK_RETRY, td);
+		}
+		/*
+		 * get unionfs vnode.
+		 */
+		else
+			error = unionfs_nodeget(dvp->v_mount, uvp, lvp,
+			    dvp, &vp, cnp, td);
 		if (error != 0) {
 			UNIONFSDEBUG("unionfs_lookup: Unable to create unionfs vnode.");
 			goto unionfs_lookup_out;
@@ -320,7 +343,7 @@ unionfs_lookup(struct vop_cachedlookup_a
 
 	*(ap->a_vpp) = vp;
 
-	if (cnflags & MAKEENTRY)
+	if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK)
 		cache_enter(dvp, vp, cnp);
 
 unionfs_lookup_out:
@@ -349,6 +372,8 @@ unionfs_create(struct vop_create_args *a
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+
 	dunp = VTOUNIONFS(ap->a_dvp);
 	cnp = ap->a_cnp;
 	td = curthread;
@@ -356,7 +381,13 @@ unionfs_create(struct vop_create_args *a
 	error = EROFS;
 
 	if (udvp != NULLVP) {
-		if ((error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap)) == 0) {
+		error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap);
+		if (error != 0)
+			goto unionfs_create_abort;
+
+		if (vp->v_type == VSOCK)
+			*(ap->a_vpp) = vp;
+		else {
 			VOP_UNLOCK(vp, 0, td);
 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
 			    ap->a_dvp, ap->a_vpp, cnp, td);
@@ -364,6 +395,7 @@ unionfs_create(struct vop_create_args *a
 		}
 	}
 
+unionfs_create_abort:
 	UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error);
 
 	return (error);
@@ -379,6 +411,8 @@ unionfs_whiteout(struct vop_whiteout_arg
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+
 	dunp = VTOUNIONFS(ap->a_dvp);
 	cnp = ap->a_cnp;
 	udvp = dunp->un_uppervp;
@@ -414,6 +448,8 @@ unionfs_mknod(struct vop_mknod_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+
 	dunp = VTOUNIONFS(ap->a_dvp);
 	cnp = ap->a_cnp;
 	td = curthread;
@@ -421,7 +457,13 @@ unionfs_mknod(struct vop_mknod_args *ap)
 	error = EROFS;
 
 	if (udvp != NULLVP) {
-		if ((error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap)) == 0) {
+		error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap);
+		if (error != 0)
+			goto unionfs_mknod_abort;
+
+		if (vp->v_type == VSOCK)
+			*(ap->a_vpp) = vp;
+		else {
 			VOP_UNLOCK(vp, 0, td);
 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
 			    ap->a_dvp, ap->a_vpp, cnp, td);
@@ -429,6 +471,7 @@ unionfs_mknod(struct vop_mknod_args *ap)
 		}
 	}
 
+unionfs_mknod_abort:
 	UNIONFS_INTERNAL_DEBUG("unionfs_mknod: leave (%d)\n", error);
 
 	return (error);
@@ -448,6 +491,8 @@ unionfs_open(struct vop_open_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_open: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = 0;
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;
@@ -527,6 +572,8 @@ unionfs_close(struct vop_close_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_close: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	locked = 0;
 	unp = VTOUNIONFS(ap->a_vp);
 	cred = ap->a_cred;
@@ -654,6 +701,8 @@ unionfs_access(struct vop_access_args *a
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_access: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;
@@ -731,6 +780,8 @@ unionfs_getattr(struct vop_getattr_args 
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_getattr: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
 	uvp = unp->un_uppervp;
@@ -781,6 +832,8 @@ unionfs_setattr(struct vop_setattr_args 
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = EROFS;
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;
@@ -819,6 +872,8 @@ unionfs_read(struct vop_read_args *ap)
 
 	/* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -838,6 +893,8 @@ unionfs_write(struct vop_write_args *ap)
 
 	/* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -857,6 +914,8 @@ unionfs_lease(struct vop_lease_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_lease: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -877,6 +936,8 @@ unionfs_ioctl(struct vop_ioctl_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
  	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, ap->a_td);
 	unp = VTOUNIONFS(ap->a_vp);
 	unionfs_get_node_status(unp, ap->a_td, &unsp);
@@ -902,6 +963,8 @@ unionfs_poll(struct vop_poll_args *ap)
 	struct unionfs_node_status *unsp;
 	struct vnode   *ovp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
  	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, ap->a_td);
 	unp = VTOUNIONFS(ap->a_vp);
 	unionfs_get_node_status(unp, ap->a_td, &unsp);
@@ -922,6 +985,8 @@ unionfs_fsync(struct vop_fsync_args *ap)
 	struct unionfs_node_status *unsp;
 	struct vnode   *ovp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	unionfs_get_node_status(unp, ap->a_td, &unsp);
 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
@@ -937,36 +1002,81 @@ static int
 unionfs_remove(struct vop_remove_args *ap)
 {
 	int		error;
+	char	       *path;
 	struct unionfs_node *dunp;
 	struct unionfs_node *unp;
 	struct unionfs_mount *ump;
 	struct vnode   *udvp;
 	struct vnode   *uvp;
 	struct vnode   *lvp;
+	struct vnode   *vp;
 	struct componentname *cnp;
+	struct componentname cn;
 	struct thread  *td;
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+
 	error = 0;
 	dunp = VTOUNIONFS(ap->a_dvp);
-	unp = VTOUNIONFS(ap->a_vp);
 	udvp = dunp->un_uppervp;
-	uvp = unp->un_uppervp;
-	lvp = unp->un_lowervp;
 	cnp = ap->a_cnp;
 	td = curthread;
 
+	if (ap->a_vp->v_op != &unionfs_vnodeops) {
+		if (ap->a_vp->v_type != VSOCK)
+			return (EINVAL);
+		ump = NULL;
+		vp = uvp = lvp = NULLVP;
+		/* search vnode */
+		VOP_UNLOCK(ap->a_vp, 0, td);
+		error = unionfs_relookup(udvp, &vp, cnp, &cn, td,
+		    cnp->cn_nameptr, strlen(cnp->cn_nameptr), DELETE);
+		if (error != 0 && error != ENOENT) {
+			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
+			return (error);
+		}
+
+		if (error == 0 && vp == ap->a_vp) {
+			/* target vnode in upper */
+			uvp = vp;
+			vrele(vp);
+			path = NULL;
+		} else {
+			/* target vnode in lower */
+			if (vp != NULLVP) {
+				if (udvp == vp)
+					vrele(vp);
+				else
+					vput(vp);
+			}
+			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
+			lvp = ap->a_vp;
+			path = ap->a_cnp->cn_nameptr;
+		}
+	} else {
+		ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
+		unp = VTOUNIONFS(ap->a_vp);
+		uvp = unp->un_uppervp;
+		lvp = unp->un_lowervp;
+		path = unp->un_path;
+	}
+
 	if (udvp == NULLVP)
 		return (EROFS);
 
 	if (uvp != NULLVP) {
-		ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
-		if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP)
+		/*
+		 * XXX: if the vnode type is VSOCK, it will create whiteout
+		 *      after remove.
+		 */
+		if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS ||
+		    lvp != NULLVP)
 			cnp->cn_flags |= DOWHITEOUT;
 		error = VOP_REMOVE(udvp, uvp, cnp);
 	} else if (lvp != NULLVP)
-		error = unionfs_mkwhiteout(udvp, cnp, td, unp->un_path);
+		error = unionfs_mkwhiteout(udvp, cnp, td, path);
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error);
 
@@ -987,6 +1097,9 @@ unionfs_link(struct vop_link_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_tdvp);
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = 0;
 	needrelookup = 0;
 	dunp = VTOUNIONFS(ap->a_tdvp);
@@ -1077,7 +1190,10 @@ unionfs_rename(struct vop_rename_args *a
 	/* check for cross device rename */
 	if (fvp->v_mount != tdvp->v_mount ||
 	    (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) {
-		error = EXDEV;
+		if (fvp->v_op != &unionfs_vnodeops)
+			error = ENODEV;
+		else
+			error = EXDEV;
 		goto unionfs_rename_abort;
 	}
 
@@ -1089,6 +1205,12 @@ unionfs_rename(struct vop_rename_args *a
 	 * from/to vnode is unionfs node.
 	 */
 
+	KASSERT_UNIONFS_VNODE(fdvp);
+	KASSERT_UNIONFS_VNODE(fvp);
+	KASSERT_UNIONFS_VNODE(tdvp);
+	if (tvp != NULLVP)
+		KASSERT_UNIONFS_VNODE(tvp);
+
 	unp = VTOUNIONFS(fdvp);
 #ifdef UNIONFS_IDBG_RENAME
 	UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n", fdvp, unp->un_uppervp, unp->un_lowervp);
@@ -1258,6 +1380,8 @@ unionfs_mkdir(struct vop_mkdir_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+
 	error = EROFS;
 	dunp = VTOUNIONFS(ap->a_dvp);
 	cnp = ap->a_cnp;
@@ -1305,6 +1429,9 @@ unionfs_rmdir(struct vop_rmdir_args *ap)
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = 0;
 	dunp = VTOUNIONFS(ap->a_dvp);
 	unp = VTOUNIONFS(ap->a_vp);
@@ -1357,6 +1484,8 @@ unionfs_symlink(struct vop_symlink_args 
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_dvp);
+
 	error = EROFS;
 	dunp = VTOUNIONFS(ap->a_dvp);
 	cnp = ap->a_cnp;
@@ -1400,6 +1529,8 @@ unionfs_readdir(struct vop_readdir_args 
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = 0;
 	eofflag = 0;
 	locked = 0;
@@ -1547,6 +1678,8 @@ unionfs_readlink(struct vop_readlink_arg
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -1572,6 +1705,8 @@ unionfs_getwritemount(struct vop_getwrit
 	if (vp == NULLVP || (vp->v_mount->mnt_flag & MNT_RDONLY))
 		return (EACCES);
 
+	KASSERT_UNIONFS_VNODE(vp);
+
 	uvp = UNIONFSVPTOUPPERVP(vp);
 	if (uvp == NULLVP && VREG == vp->v_type)
 		uvp = UNIONFSVPTOUPPERVP(VTOUNIONFS(vp)->un_dvp);
@@ -1666,6 +1801,8 @@ unionfs_lock(struct vop_lock1_args *ap)
 	struct vnode   *lvp;
 	struct thread  *td;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = 0;
 	uhold = 0;
 	flags = ap->a_flags;
@@ -1787,6 +1924,8 @@ unionfs_unlock(struct vop_unlock_args *a
 	struct vnode   *uvp;
 	struct unionfs_node *unp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = 0;
 	mtxlkflag = 0;
 	uhold = 0;
@@ -1855,6 +1994,8 @@ unionfs_pathconf(struct vop_pathconf_arg
 	struct unionfs_node *unp;
 	struct vnode   *vp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -1873,6 +2014,8 @@ unionfs_advlock(struct vop_advlock_args 
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	vp = ap->a_vp;
 	td = curthread;
 
@@ -1923,6 +2066,8 @@ unionfs_strategy(struct vop_strategy_arg
 	struct unionfs_node *unp;
 	struct vnode   *vp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -1944,6 +2089,8 @@ unionfs_getacl(struct vop_getacl_args *a
 	struct unionfs_node *unp;
 	struct vnode   *vp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -1967,6 +2114,8 @@ unionfs_setacl(struct vop_setacl_args *a
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = EROFS;
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;
@@ -1999,6 +2148,8 @@ unionfs_aclcheck(struct vop_aclcheck_arg
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
 
@@ -2017,6 +2168,8 @@ unionfs_openextattr(struct vop_openextat
 	struct vnode   *vp;
 	struct vnode   *tvp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	vp = ap->a_vp;
 	unp = VTOUNIONFS(vp);
 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
@@ -2047,6 +2200,8 @@ unionfs_closeextattr(struct vop_closeext
 	struct vnode   *vp;
 	struct vnode   *tvp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	vp = ap->a_vp;
 	unp = VTOUNIONFS(vp);
 	tvp = NULLVP;
@@ -2079,6 +2234,8 @@ unionfs_getextattr(struct vop_getextattr
 	struct unionfs_node *unp;
 	struct vnode   *vp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = NULLVP;
 
@@ -2105,6 +2262,8 @@ unionfs_setextattr(struct vop_setextattr
 	struct ucred   *cred;
 	struct thread  *td;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = EROFS;
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;
@@ -2164,6 +2323,8 @@ unionfs_listextattr(struct vop_listextat
 	struct unionfs_node *unp;
 	struct vnode   *vp;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	unp = VTOUNIONFS(ap->a_vp);
 	vp = NULLVP;
 
@@ -2190,6 +2351,8 @@ unionfs_deleteextattr(struct vop_deletee
 	struct ucred   *cred;
 	struct thread  *td;
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = EROFS;
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;
@@ -2254,6 +2417,8 @@ unionfs_setlabel(struct vop_setlabel_arg
 
 	UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n");
 
+	KASSERT_UNIONFS_VNODE(ap->a_vp);
+
 	error = EROFS;
 	unp = VTOUNIONFS(ap->a_vp);
 	uvp = unp->un_uppervp;


More information about the svn-src-all mailing list