Subject: mount checking disklabel for filesystem types
To: None <tech-misc@netbsd.org>
From: None <abs@purplei.com>
List: tech-misc
Date: 09/16/2000 00:27:13
	Having to type 'mount -t cd9660 /dev/cd0a /mnt' rather than
		       'mount /dev/cd0a /mnt' always annoys me :)

	The diffs to have mount check disklabel for a filesystem type
	_only_ in the case where both device and mountpoint are specified
	without -t are quite small - attached below.

	Is there any reason why something like this isn't in the
	tree, and if not, does the following look reasonable?

		David/absolute
				       -- www.netbsd.org: No hype required --



Index: mount.8
===================================================================
RCS file: /cvsroot/basesrc/sbin/mount/mount.8,v
retrieving revision 1.29
diff -u -B -r1.29 mount.8
--- mount.8	2000/07/30 15:17:14	1.29
+++ mount.8	2000/09/15 23:14:35
@@ -69,6 +69,11 @@
 then in the
 .Dq fs_spec
 column.
+If both
+.Ar special
+and
+.Ar node
+are given, the disklabel is checked for the filesystem type.
 .Pp
 The system maintains a list of currently mounted file systems.
 If no arguments are given to
Index: mount.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/mount/mount.c,v
retrieving revision 1.47
diff -u -B -r1.47 mount.c
--- mount.c	1999/11/16 11:53:17	1.47
+++ mount.c	2000/09/15 23:14:50
@@ -61,6 +61,11 @@
 #include <string.h>
 #include <unistd.h>
 
+#define MOUNTNAMES
+#include <fcntl.h>
+#include <sys/disklabel.h>
+#include <sys/ioctl.h>
+
 #include "pathnames.h"
 
 int	debug, verbose;
@@ -72,6 +77,8 @@
 int	hasopt __P((const char *, const char *));
 const char
       **makevfslist __P((char *));
+const static char *
+	getfslab __P((const char *str));
 static void
 	mangle __P((char *, int *, const char ***, int *));
 int	mountfs __P((const char *, const char *, const char *,
@@ -247,8 +254,15 @@
 		 * a ':' or a '@' then assume that an NFS filesystem is being
 		 * specified ala Sun.
 		 */
-		if (vfslist == NULL && strpbrk(argv[0], ":@") != NULL)
-			vfstype = "nfs";
+		if (vfslist == NULL) {
+			if (strpbrk(argv[0], ":@") != NULL)
+				vfstype = "nfs";
+			else {
+				vfstype = getfslab(argv[0]);
+				if (vfstype == NULL)
+					vfstype = ffs_fstype;
+			}
+		}
 		rval = mountfs(vfstype,
 		    argv[0], argv[1], init_flags, options, NULL, 0);
 		break;
@@ -559,6 +573,39 @@
 	*argcp = argc;
 	*argvp = argv;
 	*maxargcp = maxargc;
+}
+
+const static char *
+getfslab(str)
+	const char *str;
+{
+	struct disklabel dl;
+	int fd;
+	int part;
+	const char *vfstype;
+	u_char fstype;
+
+	/* deduce the filesystem type from the disk label */
+	if ((fd = open(str, O_RDONLY)) == -1)
+		err(1, "cannot open `%s'", str);
+
+	if (ioctl(fd, DIOCGDINFO, &dl) == -1)
+		err(1, "cannot get disklabel for `%s'", str);
+
+	(void) close(fd);
+
+	part = str[strlen(str) - 1] - 'a';
+
+	if (part < 0 || part >= dl.d_npartitions)
+		errx(1, "partition `%s' is not defined on disk", str);
+
+	/* Return NULL for unknown types - caller can fall back to ffs */
+	if ((fstype = dl.d_partitions[part].p_fstype) >= FSMAXMOUNTNAMES)
+		vfstype = NULL;
+	else
+		vfstype = mountnames[fstype];
+
+	return vfstype;
 }
 
 void
Index: sys/sys/disklabel.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/disklabel.h,v
retrieving revision 1.60
diff -u -B -r1.60 disklabel.h
--- sys/sys/disklabel.h	2000/05/16 04:55:58	1.60
+++ sys/sys/disklabel.h	2000/09/15 23:24:55
@@ -1,4 +1,3 @@
-/*	$NetBSD: disklabel.h,v 1.60 2000/05/16 04:55:58 perseant Exp $	*/
 
 /*
  * Copyright (c) 1987, 1988, 1993
@@ -298,6 +297,36 @@
 	NULL		/* NULL */
 };
 #define FSMAXNAMES	(sizeof(fscknames) / sizeof(fscknames[0]) - 1)
+
+#endif
+
+#ifdef MOUNTNAMES
+/* These are the names MOUNT_XXX from <sys/mount.h> */
+static const char *const mountnames[] = {
+	NULL,		/* unused */
+	NULL,		/* swap */
+	NULL,		/* Version 6 */
+	NULL,		/* Version 7 */
+	NULL,		/* System V */
+	NULL,		/* 4.1BSD */
+	NULL,		/* Eighth edition */
+	"ffs",		/* 4.2BSD */
+	"msdos",	/* MSDOS */
+	"lfs",		/* 4.4LFS */
+	NULL,		/* unknown */
+	NULL,		/* HPFS */
+	"cd9660",	/* ISO9660 */
+	NULL,		/* boot */
+	"ados",		/* ADOS */
+	NULL,		/* HFS */
+	"filecore",	/* FILECORE */
+	"ext2fs",	/* Linux Ext2 */
+	"ntfs",		/* Windows/NT */
+	NULL,		/* RAID Component */
+	NULL,		/* concatenated disk component */
+	NULL		/* NULL */
+};
+#define FSMAXMOUNTNAMES	(sizeof(mountnames) / sizeof(mountnames[0]) - 1)
 
 #endif