Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 May 2001 14:20:54 +0400 (MSD)
From:      "Vladimir B. Grebenschikov" <vova@vbook.express.ru>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/27571: Changing policy of shadowing files and directoris to upper layer in unionfs
Message-ID:  <200105231020.OAA01356@vbook.express.ru>

next in thread | raw e-mail | index | archive | help

>Number:         27571
>Category:       kern
>Synopsis:       Changing policy of shadowing files and directoris to upper layer in unionfs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 23 03:30:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Vladimir B. Grebenschikov
>Release:        FreeBSD 4.3-RELEASE i386
>Organization:
TSB "Russian Express"
>Environment:

FreeBSD wda0.express.ru 4.3-RELEASE FreeBSD 4.3-RELEASE #2: Wed May 23 11:22:45
MSD 2001     root@wda0.express.ru:/usr/src/sys/compile/WDA0  i386

>Description:

  While working with unionfs:
  If a directory is found in the lower layer, and there is no entry in the
  upper layer, then a shadow directory will be created in the upperlayer.
  It will be owned by the user who originally did the union mount, with
  mode `rwxrwxrwx'' (0777) modified by the umask in effect at that time.
  So inbasic unionfs policy do all think like user copy directory structure
  by his own hand.

  I want possibility to give user exactly same stucture as on below layer,
  with same uid/gid/mode as on lowerlayer.

  Patch attached provide possibility use -a key to /sbin/mount_union.

  In case of the -a option the newly mirrored upper-layer directory will
  have the same attributes as the lower-layer directory.

  And same thing with files.

>How-To-Repeat:

>Fix:

--- /usr/src/sbin/mount_union/mount_union.c	Sat Oct  9 15:54:14 1999
+++ sbin/mount_union/mount_union.c	Tue May 22 15:21:46 2001
@@ -85,7 +85,7 @@
 
 	mntflags = 0;
 	args.mntflags = UNMNT_ABOVE;
-	while ((ch = getopt(argc, argv, "bo:r")) != -1)
+	while ((ch = getopt(argc, argv, "abo:r")) != -1)
 		switch (ch) {
 		case 'b':
 			args.mntflags &= ~UNMNT_OPMASK;
@@ -97,6 +97,9 @@
 		case 'r':
 			args.mntflags &= ~UNMNT_OPMASK;
 			args.mntflags |= UNMNT_REPLACE;
+			break;
+		case 'a':
+                        args.mntflags |= UNMNT_CPATTR;
 			break;
 		case '?':
 		default:
--- /usr/src/sbin/mount_union/mount_union.8 Wed May 23 14:08:09 2001
+++ sbin/mount_union/mount_union.8      Wed May 23 14:05:21 2001
@@ -43,7 +43,7 @@
 .Nd mount union filesystems
 .Sh SYNOPSIS
 .Nm
-.Op Fl br
+.Op Fl bra
 .Op Fl o Ar options
 .Ar directory
 .Ar uniondir
@@ -87,6 +87,9 @@
 .It Fl r
 Hide the lower layer completely in the same way as mounting with
 .Xr mount_null 8 .
+.It Fl a
+Changes the policy of attributes set up during the creation of a new 
+upper-layer shadow file or directory.
 .El
 .Pp
 To enforce filesystem security, the user mounting the filesystem
@@ -103,6 +106,8 @@
 with mode
 .Dq rwxrwxrwx
 (0777) modified by the umask in effect at that time.
+In case of the -a option the newly created upper-layer directory will have  
+the same attributes as the lower-layer directory.
 .Pp
 If a file exists in the upper layer then there is no way to access
 a file with the same name in the lower layer.
--- /usr/src/sys/miscfs/union/union.h	Wed Dec 29 07:54:48 1999
+++ sys/miscfs/union/union.h	Tue May 22 15:04:40 2001
@@ -48,12 +48,15 @@
 #define UNMNT_REPLACE	0x0003		/* Target replaces mount point */
 #define UNMNT_OPMASK	0x0003
 
+#define UNMNT_CPATTR    0x0004
+
 struct union_mount {
 	struct vnode	*um_uppervp;	/* UN_ULOCK holds locking state */
 	struct vnode	*um_lowervp;	/* Left unlocked */
 	struct ucred	*um_cred;	/* Credentials of user calling mount */
 	int		um_cmode;	/* cmask from mount process */
 	int		um_op;		/* Operation mode */
+	int             um_flag;
 };
 
 #ifdef _KERNEL
--- /usr/src/sys/miscfs/union/union_subr.c	Thu Dec 16 02:02:12 1999
+++ sys/miscfs/union/union_subr.c	Tue May 22 15:11:14 2001
@@ -749,6 +756,9 @@
 	int error;
 	struct vnode *lvp, *uvp;
 
+        struct union_mount *um;
+
+        um = MOUNTTOUNIONMOUNT(UNIONTOV(un)->v_mount);
 	/*
 	 * If the user does not have read permission, the vnode should not
 	 * be copied to upper layer.
@@ -784,6 +794,26 @@
 			UDEBUG(("union: copied up %s\n", un->un_path));
 
 	}
+        if(error == 0 && um->um_flag & UNMNT_CPATTR){
+                  struct vattr loattr, newattr;
+                  int aerror;
+                  struct ucred cred;
+
+                  VATTR_NULL(&loattr);
+                  cred.cr_ref = 1;
+                  cred.cr_uid = 0;
+                  cred.cr_ngroups = 1;
+                  cred.cr_groups[0] = 0;
+                  cred.cr_uidinfo = 0;
+                  aerror = VOP_GETATTR(lvp, &loattr, &cred, p);
+                  if(aerror == 0) {
+                          VATTR_NULL(&newattr);
+                          newattr.va_uid = loattr.va_uid;
+                          newattr.va_gid = loattr.va_gid;
+                          aerror = VOP_SETATTR(uvp, &newattr, &cred, p);
+                  }
+        }
+out:;
 	VOP_UNLOCK(uvp, 0, p);
 	union_newupper(un, uvp);
 	KASSERT(uvp->v_usecount > 0, ("copy: uvp refcount 0: %d", uvp->v_usecount));
--- /usr/src/sys/miscfs/union/union_vfsops.c	Sun Dec 19 09:07:52 1999
+++ sys/miscfs/union/union_vfsops.c	Tue May 22 15:12:36 2001
@@ -185,6 +185,7 @@
 	bzero(um, sizeof(struct union_mount));
 
 	um->um_op = args.mntflags & UNMNT_OPMASK;
+	um->um_flag = args.mntflags;
 
 	switch (um->um_op) {
 	case UNMNT_ABOVE:
--- /usr/src/sys/miscfs/union/union_vnops.c	Thu Dec 16 02:02:14 1999
+++ sys/miscfs/union/union_vnops.c	Tue May 22 15:14:31 2001
@@ -506,6 +516,10 @@
 	/* case 2. */
 	if (uerror != 0 /* && (lerror == 0) */ ) {
 		if (lowervp->v_type == VDIR) { /* case 2b. */
+			struct vattr loattr, newattr;
+                        int aerror;
+                        struct ucred cred;
+
 			KASSERT(uppervp == NULL, ("uppervp unexpectedly non-NULL"));
 			/*
 			 * oops, uppervp has a problem, we may have to shadow.
@@ -515,6 +529,21 @@
 				error = uerror;
 				goto out;
 			}
+                        if(um->um_flag & UNMNT_CPATTR) {
+                                VATTR_NULL(&loattr);
+                                cred.cr_ref = 1;
+                                cred.cr_uid = 0;
+                                cred.cr_ngroups = 1;
+                                cred.cr_groups[0] = 0;
+                                cred.cr_uidinfo = 0;
+                                aerror = VOP_GETATTR(lowervp, &loattr, &cred, cnp->cn_proc);
+                                if(aerror == 0) {
+                                        VATTR_NULL(&newattr);
+                                        newattr.va_uid = loattr.va_uid;
+                                        newattr.va_gid = loattr.va_gid;
+                                        aerror = VOP_SETATTR(uppervp, &newattr, &cred, p);
+                                }
+                        }
 		}
 	}
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200105231020.OAA01356>