Subject: expanding available mount flags
To: None <tech-kern@netbsd.org>
From: Darrin B. Jewell <dbj@netbsd.org>
List: tech-kern
Date: 10/13/2003 10:12:29
--=-=-=


Since we are down to our last __MNT_UNUSED flag, I have grabbed
a couple of extra flags by adding an internal mnt_iflag field
to "struct mount" and moving the MNT_GONE, MNT_UNMOUNT, and
MNT_WANTRDWR flags into that field.  I include below the
diff for review.

If we need a couple more flags, we could also choose to reuse
MNT_EXNORESPORT, MNT_EXKERB, MNT_EXPORTANON since these are
passed to mount(2) only in the ex_flags field of struct export_args
and are never set in mnt_flags or exported by statfs().

Before we use up the last flag, we may want to consider using
that flag to provide expansion while mantaining backward
compability.  For example, we could add a flag MNT_VERSIONED,
which would indicate that the structure passed in the
"void *data" argument is versioned.  Then either ufs_args
could be versioned or a filesstem independent and versioned mount
structure could be added at the top of the filesystem specific
structure and additional flags could be added there.

Alternately, we may at some point wish to consider a new
mount system call, perhaps importing nmount(2) from freebsd
or doing something else.  This would be a bigger project,
be we probably want to start thinking about what is the
best plan for long term maintainability.

Please review and comment on the following patch.

Thanks,
Darrin


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=mount.diff
Content-Description: patch to add internal mount flags field

Index: src/sys/fs/msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.9
diff -u -r1.9 msdosfs_vfsops.c
--- src/sys/fs/msdosfs/msdosfs_vfsops.c	7 Sep 2003 22:09:11 -0000	1.9
+++ src/sys/fs/msdosfs/msdosfs_vfsops.c	13 Oct 2003 13:47:32 -0000
@@ -297,7 +297,7 @@
 			error = EOPNOTSUPP;
 		if (error)
 			return (error);
-		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_WANTRDWR)) {
+		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_iflag & IMNT_WANTRDWR)) {
 			/*
 			 * If upgrade to read-write by non-root, then verify
 			 * that user has necessary permissions on the device.
Index: src/sys/kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.206
diff -u -r1.206 vfs_subr.c
--- src/sys/kern/vfs_subr.c	14 Sep 2003 11:09:48 -0000	1.206
+++ src/sys/kern/vfs_subr.c	13 Oct 2003 13:47:32 -0000
@@ -295,7 +295,7 @@
 {
 	int lkflags;
 
-	while (mp->mnt_flag & MNT_UNMOUNT) {
+	while (mp->mnt_iflag & IMNT_UNMOUNT) {
 		int gone;
 		
 		if (flags & LK_NOWAIT)
@@ -317,7 +317,7 @@
 		mp->mnt_wcnt++;
 		tsleep((caddr_t)mp, PVFS, "vfs_busy", 0);
 		mp->mnt_wcnt--;
-		gone = mp->mnt_flag & MNT_GONE;
+		gone = mp->mnt_iflag & IMNT_GONE;
 		
 		if (mp->mnt_wcnt == 0)
 			wakeup(&mp->mnt_wcnt);
@@ -657,7 +657,7 @@
 
 #ifdef DIAGNOSTIC
 	if ((mp != NULL) &&
-	    (mp->mnt_flag & MNT_UNMOUNT) &&
+	    (mp->mnt_iflag & IMNT_UNMOUNT) &&
 	    !(mp->mnt_flag & MNT_SOFTDEP) &&
 	    vp->v_tag != VT_VFS) {
 		panic("insmntque into dying filesystem");
Index: src/sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.194
diff -u -r1.194 vfs_syscalls.c
--- src/sys/kern/vfs_syscalls.c	13 Sep 2003 08:32:14 -0000	1.194
+++ src/sys/kern/vfs_syscalls.c	13 Oct 2003 13:47:33 -0000
@@ -305,7 +305,7 @@
 	if (SCARG(uap, flags) & MNT_RDONLY)
 		mp->mnt_flag |= MNT_RDONLY;
 	else if (mp->mnt_flag & MNT_RDONLY)
-		mp->mnt_flag |= MNT_WANTRDWR;
+		mp->mnt_iflag |= IMNT_WANTRDWR;
 	mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
 	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOCOREDUMP |
 	    MNT_NOATIME | MNT_NODEVMTIME | MNT_SYMPERM | MNT_SOFTDEP);
@@ -318,13 +318,13 @@
 	 */
 	error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p);
 	if (mp->mnt_flag & (MNT_UPDATE | MNT_GETARGS)) {
-		if (mp->mnt_flag & MNT_WANTRDWR)
+		if (mp->mnt_iflag & IMNT_WANTRDWR)
 			mp->mnt_flag &= ~MNT_RDONLY;
 		if (error || (mp->mnt_flag & MNT_GETARGS))
 			mp->mnt_flag = flag;
 		mp->mnt_flag &=~
-		    (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_WANTRDWR |
-		     MNT_GETARGS);
+		    (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_GETARGS);
+		mp->mnt_iflag &=~ IMNT_WANTRDWR;
 		if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0) {
 			if (mp->mnt_syncer == NULL)
 				error = vfs_allocate_syncvnode(mp);
@@ -511,7 +511,7 @@
 	if (used_syncer == 0)
 		lockmgr(&syncer_lock, LK_RELEASE, NULL);
 
-	mp->mnt_flag |= MNT_UNMOUNT;
+	mp->mnt_iflag |= IMNT_UNMOUNT;
 	mp->mnt_unmounter = p;
 	lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock);
 	if (mp->mnt_flag & MNT_EXPUBLIC)
@@ -529,7 +529,7 @@
 	if (error) {
 		if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0)
 			(void) vfs_allocate_syncvnode(mp);
-		mp->mnt_flag &= ~MNT_UNMOUNT;
+		mp->mnt_iflag &= ~IMNT_UNMOUNT;
 		mp->mnt_unmounter = NULL;
 		mp->mnt_flag |= async;
 		lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
@@ -550,7 +550,7 @@
 	mp->mnt_op->vfs_refcount--;
 	if (LIST_FIRST(&mp->mnt_vnodelist) != NULL)
 		panic("unmount: dangling vnode");
-	mp->mnt_flag |= MNT_GONE;
+	mp->mnt_iflag |= IMNT_GONE;
 	lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock);
 	if (used_syncer)
 		lockmgr(&syncer_lock, LK_RELEASE, NULL);
Index: src/sys/sys/mount.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mount.h,v
retrieving revision 1.111
diff -u -r1.111 mount.h
--- src/sys/sys/mount.h	7 Aug 2003 16:34:09 -0000	1.111
+++ src/sys/sys/mount.h	13 Oct 2003 13:47:33 -0000
@@ -132,6 +132,7 @@
 	struct vnodelst	mnt_vnodelist;		/* list of vnodes this mount */
 	struct lock	mnt_lock;		/* mount structure lock */
 	int		mnt_flag;		/* flags */
+	int		mnt_iflag;		/* internal flags */
 	int		mnt_maxsymlinklen;	/* max size of short symlink */
 	int		mnt_fs_bshift;		/* offset shift for lblkno */
 	int		mnt_dev_bshift;		/* shift for device sectors */
@@ -151,6 +152,9 @@
  */
 
 #define __MNT_UNUSED3	0x00800000
+#define	__MNT_UNUSED4	0x00010000
+#define	__MNT_UNUSED5	0x00020000
+#define	__MNT_UNUSED6	0x00040000
 
 #define	MNT_RDONLY	0x00000001	/* read only filesystem */
 #define	MNT_SYNCHRONOUS	0x00000002	/* file system written synchronously */
@@ -219,10 +223,6 @@
 
 /*
  * External filesystem control flags.
- *
- * MNT_MLOCK lock the mount entry so that name lookup cannot proceed
- * past the mount point.  This keeps the subtree stable during mounts
- * and unmounts.
  */
 #define	MNT_UPDATE	0x00010000	/* not a real mount, just an update */
 #define	MNT_DELEXPORT	0x00020000	/* delete export host lists */
@@ -236,28 +236,25 @@
 	{ MNT_RELOAD,		1,	"reload filesystem data" }, \
 	{ MNT_FORCE,		1,	"force unmount or readonly change" }, \
 	{ MNT_GETARGS,		1,	"retrieve mount arguments" },
+
+#define __MNT_FLAGS \
+	__MNT_BASIC_FLAGS \
+	__MNT_EXPORTED_FLAGS \
+	__MNT_INTERNAL_FLAGS \
+	__MNT_EXTERNAL_FLAGS
+
 /*
  * Internal filesystem control flags.
+ * These are set in struct mount mnt_iflag.
  *
- * MNT_UNMOUNT locks the mount entry so that name lookup cannot proceed
+ * IMNT_UNMOUNT locks the mount entry so that name lookup cannot proceed
  * past the mount point.  This keeps the subtree stable during mounts
  * and unmounts.
  */
-#define	MNT_GONE	0x00200000	/* filesystem is gone.. */
-#define MNT_UNMOUNT	0x01000000	/* unmount in progress */
-#define MNT_WANTRDWR	0x02000000	/* upgrade to read/write requested */
-
-#define __MNT_CONTROL_FLAGS \
-	{ MNT_GONE,		0,	"gone" }, \
-	{ MNT_UNMOUNT,		0,	"unmount in progress" }, \
-	{ MNT_WANTRDWR,		0,	"upgrade to read/write requested" },
+#define	IMNT_GONE	0x00000001	/* filesystem is gone.. */
+#define	IMNT_UNMOUNT	0x00000002	/* unmount in progress */
+#define	IMNT_WANTRDWR	0x00000004	/* upgrade to read/write requested */
 
-#define __MNT_FLAGS \
-	__MNT_BASIC_FLAGS \
-	__MNT_EXPORTED_FLAGS \
-	__MNT_INTERNAL_FLAGS \
-	__MNT_EXTERNAL_FLAGS \
-	__MNT_CONTROL_FLAGS
 /*
  * Sysctl CTL_VFS definitions.
  *
Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.61
diff -u -r1.61 ext2fs_vfsops.c
--- src/sys/ufs/ext2fs/ext2fs_vfsops.c	7 Aug 2003 16:34:27 -0000	1.61
+++ src/sys/ufs/ext2fs/ext2fs_vfsops.c	13 Oct 2003 13:47:33 -0000
@@ -297,7 +297,7 @@
 			if (error)
 				return (error);
 		}
-		if (fs->e2fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
+		if (fs->e2fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
 			/*
 			 * If upgrade to read-write by non-root, then verify
 			 * that user has necessary permissions on the device.
Index: src/sys/ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.51
diff -u -r1.51 ffs_softdep.c
--- src/sys/ufs/ffs/ffs_softdep.c	7 Sep 2003 11:55:43 -0000	1.51
+++ src/sys/ufs/ffs/ffs_softdep.c	13 Oct 2003 13:47:35 -0000
@@ -827,7 +827,7 @@
 	 * activity can keep us busy forever, so we just fail with EBUSY.
 	 */
 	if (loopcnt == 0) {
-		if (oldmnt->mnt_flag & MNT_UNMOUNT)
+		if (oldmnt->mnt_iflag & IMNT_UNMOUNT)
 			panic("softdep_flushfiles: looping");
 		error = EBUSY;
 	}
Index: src/sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.123
diff -u -r1.123 ffs_vfsops.c
--- src/sys/ufs/ffs/ffs_vfsops.c	25 Sep 2003 23:39:17 -0000	1.123
+++ src/sys/ufs/ffs/ffs_vfsops.c	13 Oct 2003 13:47:35 -0000
@@ -256,7 +256,7 @@
 	if (error == 0 && p->p_ucred->cr_uid != 0) {
 		accessmode = VREAD;
 		if (update ?
-		    (mp->mnt_flag & MNT_WANTRDWR) != 0 :
+		    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
 		    (mp->mnt_flag & MNT_RDONLY) == 0)
 			accessmode |= VWRITE;
 		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
@@ -374,7 +374,7 @@
 				return (error);
 		}
 
-		if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
+		if (fs->fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
 			/*
 			 * Changing from read-only to read/write
 			 */
Index: src/sys/ufs/lfs/lfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_subr.c,v
retrieving revision 1.44
diff -u -r1.44 lfs_subr.c
--- src/sys/ufs/lfs/lfs_subr.c	7 Sep 2003 11:44:22 -0000	1.44
+++ src/sys/ufs/lfs/lfs_subr.c	13 Oct 2003 13:47:35 -0000
@@ -514,7 +514,7 @@
 			if (sync)
 				lfs_writesuper(fs, fs->lfs_sboffs[fs->lfs_activesb]);
 			lfs_writesuper(fs, fs->lfs_sboffs[1 - fs->lfs_activesb]);
-			if (!(fs->lfs_ivnode->v_mount->mnt_flag & MNT_UNMOUNT))
+			if (!(fs->lfs_ivnode->v_mount->mnt_iflag & IMNT_UNMOUNT))
 				lfs_auto_segclean(fs);
 			fs->lfs_activesb = 1 - fs->lfs_activesb;
 			simple_lock(&fs->lfs_interlock);
Index: src/sys/ufs/lfs/lfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vfsops.c,v
retrieving revision 1.131
diff -u -r1.131 lfs_vfsops.c
--- src/sys/ufs/lfs/lfs_vfsops.c	7 Sep 2003 21:00:36 -0000	1.131
+++ src/sys/ufs/lfs/lfs_vfsops.c	13 Oct 2003 13:47:35 -0000
@@ -355,7 +355,7 @@
 	if (mp->mnt_flag & MNT_UPDATE) {
 		ump = VFSTOUFS(mp);
 		fs = ump->um_lfs;
-		if (fs->lfs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
+		if (fs->lfs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
 			/*
 			 * If upgrade to read-write by non-root, then verify
 			 * that user has necessary permissions on the device.
Index: src/sys/ufs/lfs/lfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v
retrieving revision 1.118
diff -u -r1.118 lfs_vnops.c
--- src/sys/ufs/lfs/lfs_vnops.c	24 Sep 2003 10:22:54 -0000	1.118
+++ src/sys/ufs/lfs/lfs_vnops.c	13 Oct 2003 13:47:36 -0000
@@ -917,7 +917,7 @@
 	struct timespec ts;
 
 	if (vp == ip->i_lfs->lfs_ivnode &&
-	    vp->v_mount->mnt_flag & MNT_UNMOUNT)
+	    vp->v_mount->mnt_iflag & IMNT_UNMOUNT)
 		return 0;
 
 	if (vp->v_usecount > 1 && vp != ip->i_lfs->lfs_ivnode) {
@@ -1222,7 +1222,7 @@
 	}
 
 	/* Avoid locking a draining lock */
-	if (ap->a_vp->v_mount->mnt_flag & MNT_UNMOUNT) {
+	if (ap->a_vp->v_mount->mnt_iflag & IMNT_UNMOUNT) {
 		return ESHUTDOWN;
 	}
 
Index: src/sys/ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.52
diff -u -r1.52 mfs_vfsops.c
--- src/sys/ufs/mfs/mfs_vfsops.c	7 Aug 2003 16:34:41 -0000	1.52
+++ src/sys/ufs/mfs/mfs_vfsops.c	13 Oct 2003 13:47:36 -0000
@@ -292,7 +292,7 @@
 			if (error)
 				return (error);
 		}
-		if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
+		if (fs->fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR))
 			fs->fs_ronly = 0;
 		if (args.fspec == 0)
 			return (vfs_export(mp, &ump->um_export, &args.export));

--=-=-=--