*BSD News Article 66588


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!news.rmit.EDU.AU!news.unimelb.EDU.AU!munnari.OZ.AU!news.ecn.uoknor.edu!paladin.american.edu!gatech!newsfeed.internetmci.com!news.inc.net!trellis.wwnet.com!agis!frankensun.altair.com!wlbr!moe!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: "mount -o update" doesn't do anything (#316)
Organization: 2BSD, Simi Valley CA USA
Message-ID: <Dq79G6.A9K@moe.2bsd.com>
Date: Sun, 21 Apr 1996 06:45:42 GMT
Lines: 476

Subject: "mount -o update" doesn't do anything (#316)
Index:	sys/ufs_mount.c,etc/mount/<several> 2.11BSD

Description:
	Mount options (noexec, nosuid, ...) can not be changed without
	unmounting and remounting a filesystem because the "-u" (also
	known as "-o update") switch is ignored by the kernel.

Repeat-By:
	mount -u -o nodev /usr
	mount

	Note that 'nodev' does not appear in the line for /usr.

	Also if it is desired to turn off an option it can't be done
	except by unmounting the filesystem and remounting it.

Fix:
	mount(8) itself changes very little, it was already parsing the
	'-u' and '-o update' options and passing them to the kernel.  The
	changes to mount(8) add the 'async' option and update the man page.

	ufs_mount.c is where all the interesting changes take place.  Attention
	is paid to the MNT_UPDATE flag now.  The previous hack to update only
	the root filesystem goes away in favor of a more general method which
	works for all filesystems.  Oh - in case anyone's counting, despite
	the size of the changes to ufs_mount.c the growth in the kernel's
	text is only 84 bytes.

	NOTE:  it is possible to update a ReadOnly filesystem to ReadWrite
	       now but NOT the reverse.  All other options can be toggled
	       on/off as desired.

	       Kernel support for the 'async' and 'sync' options is in
	       the planning stage now.  Turning those options on/off will show
	       up in the output of mount(8) but will have no effect.  Toggling
	       the other options (nodev, etc) will do the expected thing.

	To install the update cut where indicated, saving to a file (/tmp/316)
	and then:

		patch -p0 < /tmp/316
		cd /usr/src/etc/mount
		make
		make install
		make clean

	next a new kernel needs to be compiled and installed:

		cd /sys/YOUR_KERNEL_NAME
		make

	if no errors were encountered (overlays too big, etc):

		make install
		reboot

	As always this and previous updates are available via anonymous
	FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the directory
	/pub/2.11BSD.

==========================cut here============================
*** /usr/src/sys/sys/ufs_mount.c.old	Fri Mar  1 21:03:35 1996
--- /usr/src/sys/sys/ufs_mount.c	Sat Apr 20 21:56:21 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ufs_mount.c	1.7 (2.11BSD GTE) 1996/3/1
   */
  
  #include "param.h"
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ufs_mount.c	1.8 (2.11BSD GTE) 1996/4/20
   */
  
  #include "param.h"
***************
*** 35,89 ****
  	dev_t dev;
  	register struct inode *ip;
  	register struct fs *fs;
! 	register struct	nameidata *ndp = &u.u_nd;
  	u_int lenon, lenfrom;
  	char	mnton[MNAMELEN], mntfrom[MNAMELEN];
  
! 	u.u_error = getmdev(&dev, uap->fspec);
! 	if (u.u_error)
  		return;
  	ndp->ni_nameiop = LOOKUP | FOLLOW;
  	ndp->ni_segflg = UIO_USERSPACE;
  	ndp->ni_dirp = (caddr_t)uap->freg;
! 	ip = namei(ndp);
! 	if (ip == NULL)
  		return;
  /*
-  * This is a hack to update the 'from' field for the root filesystem.  When
-  * the kernel boots the string 'root_device' placed there as a place holder
-  * until the "mount -a" is done from /etc/rc - at that time the name of the
-  * root device is known and passed thru to here.  If '/' is the directory
-  * then only the 'from' and 'on' fields are updated.
-  *
   * The following two copyinstr calls will not fault because getmdev() or
   * namei() would have returned an error for invalid parameters.
  */
  	copyinstr(uap->freg, mnton, sizeof (mnton) - 1, &lenon);
  	copyinstr(uap->fspec, mntfrom, sizeof (mntfrom) - 1, &lenfrom);
! 	if	(mnton[0] == '/' && mnton[1] == '\0')
  		{
  		iput(ip);
! 		if	(dev != mount[0].m_dev)
! 			return(u.u_error = EINVAL);
! 		fs = &mount[0].m_filsys;
! 		goto updname;
  		}
! 	if (ip->i_count != 1 || (ip->i_number == ROOTINO)) {
! 		iput(ip);
! 		u.u_error = EBUSY;
! 		return;
! 	}
! 	if ((ip->i_mode&IFMT) != IFDIR) {
! 		iput(ip);
! 		u.u_error = ENOTDIR;
! 		return;
! 	}
! 
! 	fs = mountfs(dev, uap->flags, ip);
! 	if (fs == 0)
! 		return;
  updname:
  	mount_updname(fs, mnton, mntfrom, lenon, lenfrom);
  }
  
  mount_updname(fs, on, from, lenon, lenfrom)
--- 35,139 ----
  	dev_t dev;
  	register struct inode *ip;
  	register struct fs *fs;
! 	struct	nameidata *ndp = &u.u_nd;
! 	struct	mount	*mp;
  	u_int lenon, lenfrom;
+ 	int	error = 0;
  	char	mnton[MNAMELEN], mntfrom[MNAMELEN];
  
! 	if	(u.u_error = getmdev(&dev, uap->fspec))
  		return;
  	ndp->ni_nameiop = LOOKUP | FOLLOW;
  	ndp->ni_segflg = UIO_USERSPACE;
  	ndp->ni_dirp = (caddr_t)uap->freg;
! 	if	((ip = namei(ndp)) == NULL)
  		return;
+ 	if ((ip->i_mode&IFMT) != IFDIR) {
+ 		error = ENOTDIR;
+ 		goto	cmnout;
+ 	}
  /*
   * The following two copyinstr calls will not fault because getmdev() or
   * namei() would have returned an error for invalid parameters.
  */
  	copyinstr(uap->freg, mnton, sizeof (mnton) - 1, &lenon);
  	copyinstr(uap->fspec, mntfrom, sizeof (mntfrom) - 1, &lenfrom);
! 
! 	if	(uap->flags & MNT_UPDATE)
  		{
+ 		fs = ip->i_fs;
+ 		mp = (struct mount *)
+ 			((int)fs - offsetof(struct mount, m_filsys));
+ 		if	(ip->i_number != ROOTINO)
+ 			{
+ 			error = EINVAL;		/* Not a mount point */
+ 			goto	cmnout;
+ 			}
+ /*
+  * Check that the device passed in is the same one that is in the mount 
+  * table entry for this mount point.
+ */
+ 		if	(dev != mp->m_dev)
+ 			{
+ 			error = EINVAL;		/* not right mount point */
+ 			goto	cmnout;
+ 			}
+ /*
+  * This is where the RW to RO transformation would be done.  It is, for now,
+  * too much work to port pages of code to do (besides which most
+  * programs get very upset at having access yanked out from under them).
+ */
+ 		if	(fs->fs_ronly == 0 && (uap->flags & MNT_RDONLY))
+ 			{
+ 			error = EPERM;		/* ! RW to RO updates */
+ 			goto	cmnout;
+ 			}
+ /*
+  * However, going from RO to RW is easy.  Then merge in the new
+  * flags (async, sync, nodev, etc) passed in from the program.
+ */
+ 		if	(fs->fs_ronly && ((uap->flags & MNT_RDONLY) == 0))
+ 			{
+ 			fs->fs_ronly = 0;
+ 			mp->m_flags &= ~MNT_RDONLY;
+ 			}
+ #define	_MF (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC | MNT_ASYNC | MNT_SYNCHRONOUS)
+ 		mp->m_flags &= ~_MF;
+ 		mp->m_flags |= (uap->flags & _MF);
+ #undef _MF
  		iput(ip);
! 		u.u_error = 0;
! 		goto	updname;
  		}
! 	else
! 		{
! /*
!  * This is where a new mount (not an update of an existing mount point) is 
!  * done.
!  *
!  * The directory being mounted on can have no other references AND can not
!  * currently be a mount point.  Mount points have an inode number of (you
!  * guessed it) ROOTINO which is 2.
! */
! 		if	(ip->i_count != 1 || (ip->i_number == ROOTINO))
! 			{
! 			error = EBUSY;
! 			goto cmnout;
! 			}
! 		fs = mountfs(dev, uap->flags, ip);
! 		if	(fs == 0)
! 			return;
! 		}
! /*
!  * Lastly, both for new mounts and updates of existing mounts, update the
!  * mounted-on and mounted-from fields.
! */
  updname:
  	mount_updname(fs, mnton, mntfrom, lenon, lenfrom);
+ 	return;
+ cmnout:
+ 	iput(ip);
+ 	return(u.u_error = error);
  }
  
  mount_updname(fs, on, from, lenon, lenfrom)
*** /usr/src/sys/h/mount.h.old	Fri Dec 29 22:00:50 1995
--- /usr/src/sys/h/mount.h	Thu Apr 18 21:26:40 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mount.h	7.2.3 (2.11BSD GTE) 1995/12/29
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)mount.h	7.2.4 (2.11BSD GTE) 1996/4/18
   */
  
  /*
***************
*** 76,86 ****
  #define	MNT_NOEXEC	0x0004		/* can't exec from filesystem */
  #define	MNT_NOSUID	0x0008		/* don't honor setuid bits on fs */
  #define	MNT_NODEV	0x0010		/* don't interpret special files */
- 
- /* 
-  * Flags set by internal operations.
- */
  #define	MNT_QUOTA	0x0020		/* quotas are enabled on filesystem */
  
  /*
   * Mask of flags that are visible to statfs().
--- 76,83 ----
  #define	MNT_NOEXEC	0x0004		/* can't exec from filesystem */
  #define	MNT_NOSUID	0x0008		/* don't honor setuid bits on fs */
  #define	MNT_NODEV	0x0010		/* don't interpret special files */
  #define	MNT_QUOTA	0x0020		/* quotas are enabled on filesystem */
+ #define	MNT_ASYNC	0x0040		/* file system written asynchronously */
  
  /*
   * Mask of flags that are visible to statfs().
*** /usr/src/etc/mount/mount.c.old	Thu Jan 25 21:10:55 1996
--- /usr/src/etc/mount/mount.c	Sat Apr 20 21:51:26 1996
***************
*** 36,42 ****
  "@(#) Copyright (c) 1980, 1989, 1993, 1994\n\
  	The Regents of the University of California.  All rights reserved.\n";
  
! static char sccsid[] = "@(#)mount.c	8.19.1 (2.11BSD) 1996/1/16";
  #endif /* not lint */
  
  #include <sys/param.h>
--- 36,42 ----
  "@(#) Copyright (c) 1980, 1989, 1993, 1994\n\
  	The Regents of the University of California.  All rights reserved.\n";
  
! static char sccsid[] = "@(#)mount.c	8.19.2 (2.11BSD) 1996/4/18";
  #endif /* not lint */
  
  #include <sys/param.h>
***************
*** 73,81 ****
  	int o_opt;
  	char *o_name;
  } optnames[] = {
- #ifdef	notnow
  	{ MNT_ASYNC,		"asynchronous" },
- #endif
  	{ MNT_NODEV,		"nodev" },
  	{ MNT_NOEXEC,		"noexec" },
  	{ MNT_NOSUID,		"nosuid" },
--- 73,79 ----
*** /usr/src/etc/mount/mount_ufs.c.old	Thu Jan 25 21:13:18 1996
--- /usr/src/etc/mount/mount_ufs.c	Thu Apr 18 21:42:33 1996
***************
*** 36,42 ****
  "@(#) Copyright (c) 1993, 1994\n\
  	The Regents of the University of California.  All rights reserved.\n";
  
! static char sccsid[] = "@(#)mount_ufs.c	8.2.1 (2.11BSD) 1996/1/16";
  #endif /* not lint */
  
  #include <sys/param.h>
--- 36,42 ----
  "@(#) Copyright (c) 1993, 1994\n\
  	The Regents of the University of California.  All rights reserved.\n";
  
! static char sccsid[] = "@(#)mount_ufs.c	8.2.2 (2.11BSD) 1996/4/18";
  #endif /* not lint */
  
  #include <sys/param.h>
***************
*** 54,62 ****
  
  static struct mntopt mopts[] = {
  	MOPT_STDOPTS,
- #ifdef	notnow
  	MOPT_ASYNC,
- #endif
  	MOPT_SYNC,
  	MOPT_UPDATE,
  	{ NULL }
--- 54,60 ----
*** /usr/src/etc/mount/mount.8.old	Tue Jan 16 22:59:36 1996
--- /usr/src/etc/mount/mount.8	Thu Apr 18 21:48:08 1996
***************
*** 29,35 ****
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .\"     @(#)mount.8	8.7.1 (2.11BSD) 1996/1/16
  .\"
  .TH MOUNT 8 "January 16, 1996"
  .UC 7
--- 29,35 ----
  .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  .\" SUCH DAMAGE.
  .\"
! .\"     @(#)mount.8	8.7.2 (2.11BSD) 1996/4/18
  .\"
  .TH MOUNT 8 "January 16, 1996"
  .UC 7
***************
*** 104,118 ****
  .B dangerous
  flag to set,
  and should not be used unless you are prepared to recreate the file
! system should your system crash.  This option is not currently implemented
! in 2.11BSD but is planned for the future.
  .TP 10
  force
  The same as
  \fB\-f\fP;
  forces the revocation of write access when trying to downgrade
! a filesystem mount status from read-write to read-only.   Currently a NOP
! in 2.11BSD.
  .TP 10
  nodev
  Do not interpret character or block special devices on the file system.
--- 104,117 ----
  .B dangerous
  flag to set,
  and should not be used unless you are prepared to recreate the file
! system should your system crash.
  .TP 10
  force
  The same as
  \fB\-f\fP;
  forces the revocation of write access when trying to downgrade
! a filesystem mount status from read-write to read-only.   This is not
! (and likely never will be) supported in 2.11BSD.
  .TP 10
  nodev
  Do not interpret character or block special devices on the file system.
***************
*** 134,147 ****
  .TP 10
  sync
  All I/O
! to the file system should be done synchronously.  Not implemented yet in
! 2.11BSD but is planned for the future.
  .TP 10
  update
  The same as
  \fB\-u\fP;
  indicate that the status of an already mounted file system should be changed.
- Not currently implemented in 2.11BSD.
  .PP
  Any additional options specific to a filesystem type that is not
  one of the internally known types (see the
--- 133,144 ----
  .TP 10
  sync
  All I/O
! to the file system should be done synchronously.
  .TP 10
  update
  The same as
  \fB\-u\fP;
  indicate that the status of an already mounted file system should be changed.
  .PP
  Any additional options specific to a filesystem type that is not
  one of the internally known types (see the
***************
*** 226,233 ****
  files on the filesystem are currently open for writing unless the
  \fB\-f\fP
  flag is also specified.
! This is currently not implemented in 2.11BSD but it is planned that 
! the ability to change the flags (nodev, nosuid, etc) will be implemented.
  The set of options is determined by first extracting the options
  for the file system from the
  .I fstab
--- 223,230 ----
  files on the filesystem are currently open for writing unless the
  \fB\-f\fP
  flag is also specified.
! This is currently not implemented in 2.11BSD.
! The ability to change the flags (nodev, nosuid, etc) is however supported.
  The set of options is determined by first extracting the options
  for the file system from the
  .I fstab
***************
*** 261,267 ****
  and this manpage were ported from 4.4BSD-Lite to 2.11BSD to gain the
  ability to set the various flags such as \fBnodev\fP, \fBnosuid\fP and
  so on.   Multiple filesystem types are not supported and several of the
! options and flags are not yet implemented.
  .SH HISTORY
  A
  .B mount
--- 258,264 ----
  and this manpage were ported from 4.4BSD-Lite to 2.11BSD to gain the
  ability to set the various flags such as \fBnodev\fP, \fBnosuid\fP and
  so on.   Multiple filesystem types are not supported and several of the
! options and flags are not implemented.
  .SH HISTORY
  A
  .B mount
*** /VERSION.old	Fri Apr 12 22:29:42 1996
--- /VERSION	Sat Apr 20 20:38:57 1996
***************
*** 1,4 ****
! Current Patch Level: 315
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 316
  
  2.11 BSD
  ============