Your CVS fix 1.109 to union_vnops.c

Takanori Watanabe takawata at init-main.com
Mon Oct 4 02:13:59 PDT 2004


In message <4160FBD9.10603 at geminix.org>, Uwe Doering wrote:
>takawata at jp.freebsd.org wrote:
>> In message <4160ED06.6070603 at geminix.org>, Uwe Doering wrote:
>> 
>>>Takanori Watanabe wrote:
>>>[...]
>>>>Ok, the issue Uwe says is when underlying filesystem and 
>>>>wrapping filesystem are diffent and if there are two files
>>>>with same identifier exists. 
>>>>And the issue I want to fix is when underlying filesystem and
>>>>wrapping filesystem are same so getcwd routine failed to distinguish 
>>>>the mount point.
>>>>
>>>>So it can be solved by translating fsid if the fsid of a file is same as
>>>>that of mountpoint. True?
>>>
>>>Correct.  In this case the inode number is guaranteed to be unique. 
>>>This might be okay as a local patch, but it is IMHO not a fix suited for 
>>>FreeBSD in general.
>> 
>> Ok. How about this?
>
>This wouldn't be correct, either.  Unionfs can be stacked, that is, you 
>can't even be sure for a single layer that the passed up va_fsid will 
>always be the same.  The underlying unionfs can be comprised of two 
>layers on two different file systems as well, and so on.  You can 
>override va_fsid only if the original file system id is guaranteed to be 
>the same for all files in that layer (single file system case).

Ok, whats next?

Index: union.h
===================================================================
RCS file: /home/ncvs/src/sys/fs/unionfs/union.h,v
retrieving revision 1.28
diff -u -r1.28 union.h
--- union.h	7 Apr 2004 20:46:03 -0000	1.28
+++ union.h	4 Oct 2004 09:03:26 -0000
@@ -44,6 +44,7 @@
 	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
Index: union_vfsops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/unionfs/union_vfsops.c,v
retrieving revision 1.67
diff -u -r1.67 union_vfsops.c
--- union_vfsops.c	30 Jul 2004 22:08:51 -0000	1.67
+++ union_vfsops.c	4 Oct 2004 09:03:26 -0000
@@ -72,6 +72,7 @@
 	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;
@@ -190,6 +191,12 @@
 				M_UNIONFSMNT, M_WAITOK | M_ZERO);
 
 	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:
Index: union_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/unionfs/union_vnops.c,v
retrieving revision 1.109
diff -u -r1.109 union_vnops.c
--- union_vnops.c	2 Oct 2004 17:17:04 -0000	1.109
+++ union_vnops.c	4 Oct 2004 09:03:27 -0000
@@ -932,6 +932,7 @@
 {
 	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_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;



More information about the freebsd-fs mailing list