summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortakawata <takawata@FreeBSD.org>2004-10-05 05:59:29 +0000
committertakawata <takawata@FreeBSD.org>2004-10-05 05:59:29 +0000
commit58f5d3f21685e512bc226f042c10d57e06bc3ba9 (patch)
treec4461ddb3400baa80838ad958f09a8ef4f580937
parent6834dc4a7a573439bc3009b71986be5e2a4a102e (diff)
downloadFreeBSD-src-58f5d3f21685e512bc226f042c10d57e06bc3ba9.zip
FreeBSD-src-58f5d3f21685e512bc226f042c10d57e06bc3ba9.tar.gz
Fix unionfs problems when a directory is mounted on other directory
with different file systems. This may cause ill things with my previous fix. Now it translate fsid of direct child of mount point directory only. Pointed out by: Uwe Doering
-rw-r--r--sys/fs/unionfs/union.h1
-rw-r--r--sys/fs/unionfs/union_vfsops.c7
-rw-r--r--sys/fs/unionfs/union_vnops.c4
3 files changed, 11 insertions, 1 deletions
diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h
index f5326d4..f8af98a 100644
--- a/sys/fs/unionfs/union.h
+++ b/sys/fs/unionfs/union.h
@@ -44,6 +44,7 @@ struct union_mount {
struct ucred *um_cred; /* Credentials of user calling mount */
int um_cmode; /* cmask from mount process */
int um_op; /* Operation mode */
+ dev_t um_upperdev; /* Upper root node fsid[0]*/
};
#ifdef _KERNEL
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index 1b5293e..bf3fcfa 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -72,6 +72,7 @@ union_mount(mp, td)
struct vnode *lowerrootvp = NULLVP;
struct vnode *upperrootvp = NULLVP;
struct union_mount *um = 0;
+ struct vattr va;
struct ucred *cred = 0;
char *cp = 0, *target;
int op;
@@ -191,6 +192,12 @@ union_mount(mp, td)
um->um_op = op;
+ error = VOP_GETATTR(upperrootvp, &va, td->td_ucred, td);
+ if (error)
+ goto bad;
+
+ um->um_upperdev = va.va_fsid;
+
switch (um->um_op) {
case UNMNT_ABOVE:
um->um_lowervp = lowerrootvp;
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
index 89673df..55d1d3a 100644
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -932,6 +932,7 @@ union_getattr(ap)
{
int error;
struct union_node *un = VTOUNION(ap->a_vp);
+ struct union_mount *um = MOUNTTOUNIONMOUNT(ap->a_vp->v_mount);
struct vnode *vp;
struct vattr *vap;
struct vattr va;
@@ -972,7 +973,8 @@ union_getattr(ap)
union_newsize(ap->a_vp, VNOVAL, vap->va_size);
}
- ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
+ if (vap->va_fsid == um->um_upperdev)
+ vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
if ((vap != ap->a_vap) && (vap->va_type == VDIR))
ap->a_vap->va_nlink += vap->va_nlink;
OpenPOWER on IntegriCloud