From: Andries.Brouwer@cwi.nl
To: torvalds@transmeta.com, viro@math.psu.edu
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC][PATCH] parser for mount options
Date: Tue, 7 Aug 2001 21:51:06 GMT [thread overview]
Message-ID: <200108072151.VAA25091@vlet.cwi.nl> (raw)
> OK, folks - here's an implementation of parser for mount options.
Good!
I did the same for 1.3.61 long ago. A fragment:
(for msdos)
+ struct {
+ int check, conversion, uid, gid, umask;
+ int blksize, fat, debug, quiet, dotsOK, sys_immutable;
+ } opt = {
+ 'n', 'b', current->uid, current->gid, current->fs->umask,
+ 512, 0, 0, 0, 0, 0
+ };
+
+ typedef char *(C[]);
+ struct mount_option opts[] = {
+ { "check", OPT_STRING,
+ &(C){"relaxed", "normal", "strict", 0}, &opt.check},
+ { "conv", OPT_STRING,
+ &(C){"binary", "text", "auto", 0}, &opt.conversion},
+ { "uid", OPT_INT, 0, &opt.uid},
+ { "gid", OPT_INT, 0, &opt.gid},
+ { "umask", OPT_INT_8, 0, &opt.umask},
+ { "blocksize", OPT_INT, 0, &opt.blksize},
+ { "fat", OPT_INT, 0, &opt.fat},
+ { "debug", OPT_BOOL_01, 0, &opt.debug},
+ { "quiet", OPT_BOOL_01, 0, &opt.quiet},
+ { "dots", OPT_BOOL_NY, 0, &opt.dotsOK},
+ { "dotsOK", OPT_STRING, &(C){"yes", "no", 0}, &opt.dotsOK},
+ { "sys_immutable", OPT_BOOL_01, 0, &opt.sys_immutable}
+ };
(for iso9660)
+ struct {
+ int map, rock, cruft, unhide, check;
+ int conversion, blocksize, mode, uid, gid;
+ } opt = {
+ 'n', 'y', 'n', 'n', 's',
+ 'b', 1024, S_IRUGO, 0, 0
+ };
+
+ typedef char *(C[]);
+ struct mount_option opts[] = {
+ { "map", OPT_STRING, &(C){"normal", "off", 0}, &opt.map},
+ { "rock", OPT_BOOL_NY, 0, &opt.rock},
+ { "cruft", OPT_BOOL_NY, 0, &opt.cruft},
+ { "unhide", OPT_BOOL_NY, 0, &opt.unhide},
+ { "check", OPT_STRING, &(C){"relaxed", "strict", 0}, &opt.check},
+ { "conv", OPT_STRING,
+ &(C){"binary", "text", "mtext", "auto", 0}, &opt.conversion},
+ { "blocksize", OPT_INT, 0, &opt.blocksize}, /* used to be "block" */
+ { "mode", OPT_INT_8, 0, &opt.mode}, /* used to be OPT_INT_10 */
+ { "uid", OPT_INT, 0, &opt.uid},
+ { "gid", OPT_INT, 0, &opt.gid}
+ };
with call for each filesystem
parse_mount_options((char *) data, SIZE(opts), opts);
I am not sure which of the two versions I prefer.
For example, the above setup shows very clearly what the defaults are.
Also, you still have a lot of code for each filesystem
that calls strtok() and math_token() and does a switch().
I only have this single call parse_mount_options()
for each filesystem.
(And in the past strtok() has caused bugs because it modifies
the string it is called with. Sometimes, as in the case of vfat/msdos,
several filesystems might want to have a look.)
If you don't have any devastating comments I might brush off
this 1.3.61 patch and move it to 2.4.
Andries
PS - Let me add the code for parse_mount_options():
+/*
+ * mount option parsing
+ *
+ * Do not destroy the option string. Warn for unrecognized options,
+ * but do not fail - they might be for later kernels.
+ */
+static char *handle_option(char *arg, struct mount_option *mo, int no) {
+ char sep = *arg;
+ int eq = (sep == '=');
+ unsigned int val, l, base;
+
+ if (sep)
+ arg++;
+ if (!eq) {
+ if (mo->type & OPT_BOOL_NY) {
+ *(mo->value) = (no ? 'n' : 'y');
+ return arg;
+ } else if (mo->type & OPT_BOOL_01) {
+ *(mo->value) = !no;
+ return arg;
+ } else
+ return 0;
+ }
+ if (no || !*arg)
+ return 0;
+
+ if (mo->type & OPT_INT) {
+ switch (mo->type & OPT_INT) {
+ case OPT_INT_8:
+ base = 8; break;
+ case OPT_INT_10:
+ base = 10; break;
+ case OPT_INT_16:
+ base = 16; break;
+ default:
+ base = 0;
+ }
+ val = simple_strtoul(arg,&arg,base);
+ if (*arg == ',')
+ arg++;
+ else if (*arg)
+ return 0;
+ *(mo->value) = val;
+ return arg;
+ }
+
+ if (mo->type & OPT_STRING) {
+ /* For the time being: assume that all string values
+ start with different symbols, and that a string may
+ be abbreviated by its first symbol.
+ Introduce the flag OPT_1_OK and make stringargs an array
+ of (string, value) pairs when that isnt true anymore. */
+
+ char **smo = *(mo->stringargs);
+
+ while(smo && *smo) {
+ if (**smo != *arg) {
+ smo++;
+ continue;
+ }
+ l = strlen(*smo);
+ if (!strncmp(arg, *smo, l))
+ arg += l;
+ else
+ arg++;
+ if (*arg == ',')
+ arg++;
+ else if (*arg)
+ return 0;
+ *(mo->value) = **smo;
+ return arg;
+ }
+ }
+ return 0;
+}
+
+int parse_mount_options(char *options, int nmo, struct mount_option *mos) {
+ char sep;
+ int optl, l, n, warned = 0;
+ struct mount_option *mo;
+
+ while (options && (optl = strlen(options)) > 0) {
+ for (n = 0, mo = mos; n < nmo; n++, mo++) {
+ l = strlen(mo->name);
+ if (strncmp(options, mo->name, l) == 0
+ && ((sep = options[l]) == 0 || sep == ',' || sep == '=')) {
+ options = handle_option(options+l, mo, 0);
+ if (!options)
+ return 0; /* error */
+ goto ok;
+ }
+ if ((mo->type & OPT_BOOL)
+ && strncmp(options, "no", 2) == 0
+ && strncmp(options+2, mo->name, l) == 0
+ && ((sep = options[l+2]) == 0 || sep == ',' || sep == '=')){
+ options = handle_option(options+l+2, mo, 1);
+ if (!options)
+ return 0; /* error */
+ goto ok;
+ }
+ }
+ if (!warned++)
+ printk("Unrecognized mount option string: %s\n",
+ options);
+ while (*options && *options++ != ',') ;
+ ok:
+ }
+ return 1;
+}
next reply other threads:[~2001-08-07 21:52 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-08-07 21:51 Andries.Brouwer [this message]
2001-08-07 22:02 ` Andreas Dilger
2001-08-07 22:40 ` Alexander Viro
-- strict thread matches above, loose matches on Subject: below --
2001-08-08 11:38 Andries.Brouwer
2001-08-07 23:52 Andries.Brouwer
2001-08-08 1:14 ` Alexander Viro
2001-08-07 17:02 Alexander Viro
2001-08-07 18:06 ` Daniel Phillips
2001-08-07 18:12 ` Christoph Hellwig
2001-08-07 21:54 ` Pavel Machek
2001-08-07 22:48 ` Alexander Viro
2001-08-09 6:20 ` Albert D. Cahalan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200108072151.VAA25091@vlet.cwi.nl \
--to=andries.brouwer@cwi.nl \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
--cc=viro@math.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®