[PATCH] mount_tmpfs command

Naoya Sugioka naoya.sugioka at gmail.com
Sun Apr 4 11:26:59 PDT 2010


Hello,

Here attached is the patch for latest tmpfs related command updates:

 1. -f options for max filesize
 2. -o options now supports uid/gid/mode/inodes/size/maxfilesize
descriptive options
 3. corresponding tmpfs(5) mount_tmpfs(8) change.

Please accept this patch for latest head.

thank you,
-Naoya
diff --git a/sbin/mount_tmpfs/mount_tmpfs.8 b/sbin/mount_tmpfs/mount_tmpfs.8
index c3a9afc..d9fcfab 100644
--- a/sbin/mount_tmpfs/mount_tmpfs.8
+++ b/sbin/mount_tmpfs/mount_tmpfs.8
@@ -36,6 +36,7 @@
 .Nd mount an efficient memory file system
 .Sh SYNOPSIS
 .Nm
+.Op Fl f Ar maxfilesize
 .Op Fl g Ar group
 .Op Fl m Ar mode
 .Op Fl n Ar nodes
@@ -61,6 +62,8 @@ described below.
 .Pp
 The following options are supported:
 .Bl -tag -width XoXoptions
+.It Fl f Ar maxfilesize
+Specifies the maximum file size of the file system.
 .It Fl g Ar group
 Specifies the group name or GID of the root inode of the file system.
 Defaults to the mount point's GID.
@@ -78,9 +81,11 @@ Options are specified with a
 flag followed by a comma-separated string of options.
 See the
 .Xr mount 8
+and
+.Xr tmpfs 5
 man page for possible options and their meanings.
 .It Fl s Ar size
-Specifies the total file system size in bytes.
+Specifies the total file system size.
 If zero is given (the default), the available amount of memory (including
 main memory and swap space) will be used.
 Note that four megabytes are always reserved for the system and cannot
@@ -118,13 +123,14 @@ group, with a restricted 0700 mode:
 .Pp
 .Ic "mount -t tmpfs -o -s20M -o -ujoe -o -gusers -o -m0700 tmpfs /mnt"
 .Pp
-See
-.Pa /usr/share/examples/fstab/fstab.ramdisk
-for some examples on how to add tmpfs entries to
-.Pa /etc/fstab .
+or
+.Pp
+.Ic "mount -t tmpfs -o size=20M,uid=joe,gid=users,mode=0700 tmpfs /mnt"
+.Pp
 .Sh SEE ALSO
 .Xr fstab 5 ,
-.Xr mount 8
+.Xr mount 8 ,
+.Xr tmpfs 5
 .Sh HISTORY
 The
 .Nm
diff --git a/sbin/mount_tmpfs/mount_tmpfs.c b/sbin/mount_tmpfs/mount_tmpfs.c
index 98d221d..f36787d 100644
--- a/sbin/mount_tmpfs/mount_tmpfs.c
+++ b/sbin/mount_tmpfs/mount_tmpfs.c
@@ -58,8 +58,18 @@
 
 /* --------------------------------------------------------------------- */
 
+#define MOPT_TMPFSOPTS	\
+	{ "gid=",	0,	MNT_GID, 1},	\
+	{ "uid=",	0,	MNT_UID, 1},	\
+	{ "mode=",	0,	MNT_MODE, 1},	\
+	{ "inodes=",	0,	MNT_INODES, 1},	\
+	{ "size=",	0,	MNT_SIZE, 1},	\
+	{ "maxfilesize=",	0,	MNT_MAXFSIZE, 1}
+
+
 static const struct mntopt mopts[] = {
 	MOPT_STDOPTS,
+	MOPT_TMPFSOPTS,
 	MOPT_NULL
 };
 
@@ -68,6 +78,7 @@ static const struct mntopt mopts[] = {
 static gid_t	a_gid(char *);
 static uid_t	a_uid(char *);
 static mode_t	a_mask(char *);
+static int64_t a_number(char *s);
 static void	usage(void) __dead2;
 
 /* --------------------------------------------------------------------- */
@@ -82,14 +93,16 @@ mount_tmpfs_parseargs(int argc, char *argv[],
 	gid_t gid;
 	uid_t uid;
 	mode_t mode;
-	int64_t tmpnumber;
 	struct stat sb;
+	int extend_flags = 0;
+	char *ptr, *delim;
 
 	/* Set default values for mount point arguments. */
 	memset(args, 0, sizeof(*args));
 	args->ta_version = TMPFS_ARGS_VERSION;
 	args->ta_size_max = 0;
 	args->ta_nodes_max = 0;
+	args->ta_maxfsize_max = 0;
 	*mntflags = 0;
 
 	gidset = 0; gid = 0;
@@ -97,8 +110,12 @@ mount_tmpfs_parseargs(int argc, char *argv[],
 	modeset = 0; mode = 0;
 
 	optind = optreset = 1;
-	while ((ch = getopt(argc, argv, "g:m:n:o:s:u:")) != -1 ) {
+	while ((ch = getopt(argc, argv, "f:g:m:n:o:s:u:")) != -1 ) {
 		switch (ch) {
+		case 'f':
+			args->ta_maxfsize_max = a_number(optarg);
+			break;
+
 		case 'g':
 			gid = a_gid(optarg);
 			gidset = 1;
@@ -110,23 +127,97 @@ mount_tmpfs_parseargs(int argc, char *argv[],
 			break;
 
 		case 'n':
-			if (dehumanize_number(optarg, &tmpnumber) < 0) {
-				fprintf(stderr, "bad number for -n\n");
-				usage();
-			}
-			args->ta_nodes_max = tmpnumber;
+			args->ta_nodes_max = a_number(optarg);
 			break;
 
 		case 'o':
-			getmntopts(optarg, mopts, mntflags, 0);
+			getmntopts(optarg, mopts, mntflags, &extend_flags);
+			if (extend_flags & MNT_GID) {
+				ptr = strstr(optarg, "gid=");
+				if(ptr) {
+					delim = strstr(ptr, ",");
+					if (delim) {
+						*delim = '\0';
+						gid = a_gid(ptr + 4);
+						*delim = ',';
+					} else
+						gid = a_gid(ptr + 4);
+					gidset = 1;
+					
+				}
+				extend_flags ^= MNT_GID;
+			}
+			if (extend_flags & MNT_UID) {
+				ptr = strstr(optarg, "uid=");
+				if(ptr) {
+					delim = strstr(ptr, ",");
+					if (delim) {
+						*delim = '\0';
+						uid = a_uid(ptr + 4);
+						*delim = ',';
+					} else 
+						uid = a_uid(ptr + 4);
+					uidset = 1;
+				}
+				extend_flags ^= MNT_UID;
+			}
+			if (extend_flags & MNT_MODE) {
+				ptr = strstr(optarg, "mode=");
+				if(ptr) {
+					delim = strstr(ptr, ",");
+					if (delim) {
+						*delim = '\0';
+						mode = a_mask(ptr + 5);
+						*delim = ',';
+					} else 
+						mode = a_mask(ptr + 5);
+					modeset = 1;
+				}
+				extend_flags ^= MNT_MODE;
+			}
+			if (extend_flags & MNT_INODES) {
+				ptr = strstr(optarg, "inodes=");
+				if(ptr) {
+					delim = strstr(ptr, ",");
+					if (delim) {
+						*delim = '\0';
+						args->ta_nodes_max = a_number(ptr + 7);
+						*delim = ',';
+					} else
+						args->ta_nodes_max = a_number(ptr + 7);
+				}
+				extend_flags ^= MNT_INODES;
+			}
+			if (extend_flags & MNT_SIZE) {
+				ptr = strstr(optarg, "size=");
+				if(ptr) {
+					delim = strstr(ptr, ",");
+					if (delim) {
+						*delim = '\0';
+						args->ta_size_max = a_number(ptr + 5);
+						*delim = ',';
+					} else
+						args->ta_size_max = a_number(ptr + 5);
+				}
+				extend_flags ^= MNT_SIZE;
+			}
+			if (extend_flags & MNT_MAXFSIZE) {
+				ptr = strstr(optarg, "maxfilesize=");
+				if(ptr) {
+					delim = strstr(ptr, ",");
+					if (delim) {
+						*delim = '\0';
+						args->ta_maxfsize_max = a_number(ptr + 12);
+						*delim = ',';
+					} else
+						args->ta_maxfsize_max = a_number(ptr + 12);
+				}
+				extend_flags ^= MNT_MAXFSIZE;
+			}
 			break;
 
 		case 's':
-			if (dehumanize_number(optarg, &tmpnumber) < 0) {
-				fprintf(stderr, "bad number for -s\n");
-				usage();
-			}
-			args->ta_size_max = tmpnumber;
+			args->ta_size_max = a_number(optarg);
 			break;
 
 		case 'u':
@@ -205,19 +296,29 @@ a_mask(char *s)
 	done = 0;
 	if (*s >= '0' && *s <= '7') {
 		done = 1;
-		rv = strtol(optarg, &ep, 8);
+		rv = strtol(s, &ep, 8);
 	}
 	if (!done || rv < 0 || *ep)
 		errx(EX_USAGE, "invalid file mode: %s", s);
 	return (rv);
 }
 
+static int64_t
+a_number(char *s)
+{
+	int64_t rv=0;
+
+	if (dehumanize_number(s, &rv) < 0)
+		errx(EX_USAGE, "bad number for option: %s", s);
+	return (rv);
+}
+
 static void
 usage(void)
 {
 	(void)fprintf(stderr,
 	    "Usage: %s [-g group] [-m mode] [-n nodes] [-o options] [-s size]\n"
-	    "           [-u user] tmpfs mountpoint\n", getprogname());
+	    "           [-u user] [-f maxfilesize]  tmpfs mountpoint\n", getprogname());
 	exit(1);
 }
 
diff --git a/share/man/man5/tmpfs.5 b/share/man/man5/tmpfs.5
index e2184f0..f0e2ecc 100644
--- a/share/man/man5/tmpfs.5
+++ b/share/man/man5/tmpfs.5
@@ -61,9 +61,9 @@ permissions in octal format.
 .It Cm inodes
 maximum number of inodes.
 .It Cm size
-maximum size (in bytes) for the file system.
+maximum size for the file system.
 .It Cm maxfilesize
-maximum file size (in bytes).
+maximum file size of the file system.
 .El
 .Sh DESCRIPTION
 In the
@@ -99,6 +99,19 @@ By default
 allows up to 100% of swap space to be used.
 If this is not desirable then the size option should be used to limit
 its size.
+.El
+.Pp
+Every option that accepts a numerical value as its argument can take a
+trailing
+.Sq b
+to indicate bytes (the default), a trailing
+.Sq k
+to indicate kilobytes, a trailing
+.Sq M
+to indicate megabytes or a trailing
+.Sq G
+to indicate gigabytes.
+Note that both lowercase and uppercase forms of these letters are allowed.
 .Sh EXAMPLES
 To mount a
 .Nm
diff --git a/sys/vfs/tmpfs/tmpfs_args.h b/sys/vfs/tmpfs/tmpfs_args.h
index 6601ebd..2212438 100644
--- a/sys/vfs/tmpfs/tmpfs_args.h
+++ b/sys/vfs/tmpfs/tmpfs_args.h
@@ -37,13 +37,14 @@
  * This structure is used to communicate mount parameters between userland
  * and kernel space.
  */
-#define TMPFS_ARGS_VERSION	1
+#define TMPFS_ARGS_VERSION	2
 struct tmpfs_args {
 	int			ta_version;
 
 	/* Size counters. */
 	ino_t			ta_nodes_max;
 	off_t			ta_size_max;
+	size_t			ta_maxfsize_max;
 
 	/* Root node attributes. */
 	uid_t			ta_root_uid;
@@ -51,4 +52,11 @@ struct tmpfs_args {
 	mode_t			ta_root_mode;
 };
 
+#define MNT_GID		0x00000001
+#define MNT_UID		0x00000002
+#define MNT_MODE	0x00000004
+#define MNT_INODES	0x00000008
+#define MNT_SIZE	0x00000010
+#define MNT_MAXFSIZE	0x00000020
+
 #endif /* _VFS_TMPFS_TMPFS_ARGS_H_ */
diff --git a/sys/vfs/tmpfs/tmpfs_vfsops.c b/sys/vfs/tmpfs/tmpfs_vfsops.c
index d183889..9845eb7 100644
--- a/sys/vfs/tmpfs/tmpfs_vfsops.c
+++ b/sys/vfs/tmpfs/tmpfs_vfsops.c
@@ -138,10 +138,12 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
 	vm_pindex_t pages;
 	vm_pindex_t pages_limit;
 	ino_t nodes;
+	u_int64_t	maxfsize;
 	int error;
 	/* Size counters. */
 	ino_t	nodes_max;
 	off_t	size_max;
+	size_t	maxfsize_max;
 	size_t	size;
 
 	/* Root node attributes. */
@@ -162,6 +164,7 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
 	bzero(&args, sizeof(args));
 	size_max  = 0;
 	nodes_max = 0;
+	maxfsize_max = 0;
 
 	if (path) {
 		if (data) {
@@ -171,6 +174,7 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
 		}
 		size_max = args.ta_size_max;
 		nodes_max = args.ta_nodes_max;
+		maxfsize_max = args.ta_maxfsize_max;
 		root_uid = args.ta_root_uid;
 		root_gid = args.ta_root_gid;
 		root_mode = args.ta_root_mode;
@@ -206,13 +210,18 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
 	else
 		nodes = nodes_max;
 
+	if (maxfsize_max == 0)
+		maxfsize = IDX_TO_OFF(pages_limit);
+	else
+		maxfsize = maxfsize_max;
+
 	/* Allocate the tmpfs mount structure and fill it. */
 	tmp = kmalloc(sizeof(*tmp), M_TMPFSMNT, M_WAITOK | M_ZERO);
 
 	lockinit(&(tmp->allnode_lock), "tmpfs allnode lock", 0, LK_CANRECURSE);
 	tmp->tm_nodes_max = nodes;
 	tmp->tm_nodes_inuse = 0;
-	tmp->tm_maxfilesize = IDX_TO_OFF(pages_limit);
+	tmp->tm_maxfilesize = maxfsize;
 	LIST_INIT(&tmp->tm_nodes_used);
 
 	tmp->tm_pages_max = pages;




More information about the Users mailing list