diff options
-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; |