diff options
author | takawata <takawata@FreeBSD.org> | 2004-10-05 05:59:29 +0000 |
---|---|---|
committer | takawata <takawata@FreeBSD.org> | 2004-10-05 05:59:29 +0000 |
commit | 58f5d3f21685e512bc226f042c10d57e06bc3ba9 (patch) | |
tree | c4461ddb3400baa80838ad958f09a8ef4f580937 | |
parent | 6834dc4a7a573439bc3009b71986be5e2a4a102e (diff) | |
download | FreeBSD-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.h | 1 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vfsops.c | 7 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vnops.c | 4 |
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; |