svn commit: r186110 - stable/7/sys/fs/unionfs
Daichi GOTO
daichi at FreeBSD.org
Mon Dec 15 03:56:56 UTC 2008
Author: daichi
Date: Mon Dec 15 03:56:54 2008
New Revision: 186110
URL: http://svn.freebsd.org/changeset/base/186110
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:
stable/7/sys/fs/unionfs/union.h
stable/7/sys/fs/unionfs/union_subr.c
stable/7/sys/fs/unionfs/union_vfsops.c
stable/7/sys/fs/unionfs/union_vnops.c
Modified: stable/7/sys/fs/unionfs/union.h
==============================================================================
--- stable/7/sys/fs/unionfs/union.h Mon Dec 15 02:06:02 2008 (r186109)
+++ stable/7/sys/fs/unionfs/union.h Mon Dec 15 03:56:54 2008 (r186110)
@@ -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: stable/7/sys/fs/unionfs/union_subr.c
==============================================================================
--- stable/7/sys/fs/unionfs/union_subr.c Mon Dec 15 02:06:02 2008 (r186109)
+++ stable/7/sys/fs/unionfs/union_subr.c Mon Dec 15 03:56:54 2008 (r186110)
@@ -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: stable/7/sys/fs/unionfs/union_vfsops.c
==============================================================================
--- stable/7/sys/fs/unionfs/union_vfsops.c Mon Dec 15 02:06:02 2008 (r186109)
+++ stable/7/sys/fs/unionfs/union_vfsops.c Mon Dec 15 03:56:54 2008 (r186110)
@@ -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: stable/7/sys/fs/unionfs/union_vnops.c
==============================================================================
--- stable/7/sys/fs/unionfs/union_vnops.c Mon Dec 15 02:06:02 2008 (r186109)
+++ stable/7/sys/fs/unionfs/union_vnops.c Mon Dec 15 03:56:54 2008 (r186110)
@@ -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