mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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;
+}

             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®