From: Hans Reiser <reiser@namesys.com>
To: Jeff Mahoney <jeffm@suse.com>
Cc: Reiserfs List <reiserfs-list@namesys.com>,
Edward Shishkin <edward@namesys.com>
Subject: Re: Getopt improvements
Date: Thu, 27 Feb 2003 00:10:54 +0300 [thread overview]
Message-ID: <3E5D2D5E.5090400@namesys.com> (raw)
In-Reply-To: <3E5D26A2.7010804@suse.com>
Sounds good to me. Let's see what the mailing list says, and let us
have edward test it.
Hans
Jeff Mahoney wrote:
>
> Hey guys -
>
> Here's a patch against the new reiserfs_getopt stuff.
>
> There are a few shortcomings with the existing implementation:
> 1) There's no easy way to specify the negation of an option. For
> example, in the current implementation, you can do -oremount,attrs -
> but you can't turn them off again. The only way of handling this would
> have been to add another bit.. and then you can't deal with
> -oremount,attrs,noattrs,attrs - which is the correct one in that case?
> Clearly it's the last one, but there's no way to divine that using the
> existing code.
>
> 2) All of the multiple option sets are mutually exclusive. For
> example, -ohash=r5,hash=rupasov would set BOTH FORCE_RUPASOV_HASH and
> FORCE_R5_HASH.
>
> The patch addresses both of these problems.
> The first shortcoming is solved by adding a "no_prefix" member to
> opt_desc_t, which allows the option to be negated by prefixing "no" to
> the option text. In addition, I pass in a populated mount_options so
> that bits can be set and cleared on the current running options. The
> result is that as the options are parsed, they are set or cleared in
> order, so -oattrs,noattrs,attrs results in REISERFS_ATTRS being set,
> but -oattrs,noattrs,attrs,noattrs results in it being cleared. This
> may seem silly, but -oremount prepends the mount options from fstab to
> the mount strings, so a filesytem mounted initially with -oattrs, when
> remounted with -oremount,noattrs will actually parse
> -oremount,attrs,noattrs. I've removed the SET_OPT mechanism, since it
> only sets bits, it doesn't clear them. Also, since some options aren't
> valid during remount (like hashes, conversion, etc), I've added a
> "safe_mask" that only allows the bits contained in it to be updated in
> s_mount_opts.
>
> The second shortcoming is addressed by clearing all of the bits
> contained in an arg_desc_t array before setting the final value if one
> exists. As with the above solution, the last one on the command line
> is the one that is kept. If, in the future, some multivalue options
> aren't mutually exclusive, it would be trivial to add a "opt_mutex"
> flag or similar to skip this behavior on a per-option basis.
>
> The end result is this: Except for the addition of "noattrs" as a
> demonstration, the behavior of existing options is unchanged.
> Multi-value options are now handled correctly such that only one of
> the bits can be set at any given time.
>
> Please apply.
>
> -Jeff
>
>------------------------------------------------------------------------
>
>Binary files linux-2.4.20.vanilla/fs/reiserfs/.super.c.swp and linux-2.4.20.vanilla.getopt/fs/reiserfs/.super.c.swp differ
>diff -ruN linux-2.4.20.vanilla/fs/reiserfs/super.c linux-2.4.20.vanilla.getopt/fs/reiserfs/super.c
>--- linux-2.4.20.vanilla/fs/reiserfs/super.c 2002-11-28 18:53:15.000000000 -0500
>+++ linux-2.4.20.vanilla.getopt/fs/reiserfs/super.c 2003-02-26 15:03:33.000000000 -0500
>@@ -415,6 +415,7 @@
> const arg_desc_t * values; /* list of values accepted by an option */
> int bitmask; /* bit which is to be set in mount_options bitmask when this
> option is selected, 0 is not bits are to be set */
>+ int no_prefix : 1; /* "no" can be prefixed to clear this option */
> } opt_desc_t;
>
>
>@@ -490,7 +491,13 @@
> if (bit_flags && opt->bitmask != -1 )
> set_bit (opt->bitmask, bit_flags);
> break;
>- }
>+ } else if (opt->no_prefix && !strncmp (p, "no", 2) &&
>+ !strncmp (p + 2, opt->option_name, strlen (opt->option_name))) {
>+ if (bit_flags && opt->bitmask != -1)
>+ clear_bit (opt->bitmask, bit_flags);
>+ p += 2; /* Skip the "no" */
>+ break;
>+ }
> }
> if (!opt->option_name) {
> printk ("reiserfs_getopt: unknown option \"%s\"\n", p);
>@@ -536,6 +543,14 @@
> /* values possible for this option are listed in opt->values */
> for (arg = opt->values; arg->value; arg ++) {
> if (!strcmp (p, arg->value)) {
>+ const arg_desc_t * arg_clear;
>+ /* Clear all the values from this descriptor */
>+ for (arg_clear = opt->values; arg_clear->value; arg_clear++) {
>+ if (arg_clear->bitmask != -1)
>+ clear_bit (arg_clear->bitmask, bit_flags);
>+ }
>+
>+ /* The the option we found has a bit.. set that */
> if (bit_flags && arg->bitmask != -1 )
> set_bit (arg->bitmask, bit_flags);
> return opt->arg_required;
>@@ -548,6 +563,7 @@
>
>
> /* returns 0 if something is wrong in option string, 1 - otherwise */
>+/* Caller is responsible for clearing mount_options before use if desired */
> static int reiserfs_parse_options (struct super_block * s, char * options, /* string given via mount's -o */
> unsigned long * mount_options,
> /* after the parsing phase, contains the
>@@ -559,18 +575,18 @@
> char * arg = NULL;
> char * pos;
> opt_desc_t opts[] = {
>- {"tails", 't', tails, -1},
>- {"notail", 0, 0, -1}, /* Compatibility stuff, so that -o notail for old setups still work */
>- {"conv", 0, 0, REISERFS_CONVERT},
>- {"nolog", 0, 0, -1},
>- {"replayonly", 0, 0, REPLAYONLY},
>+ {"tails", 't', tails, -1, 0},
>+ {"notail", 0, 0, -1, 0}, /* Compatibility stuff, so that -o notail for old setups still work */
>+ {"conv", 0, 0, REISERFS_CONVERT, 0},
>+ {"nolog", 0, 0, -1, 0},
>+ {"replayonly", 0, 0, REPLAYONLY, 0},
>
>- {"block-allocator", 'a', balloc, -1},
>- {"hash", 'h', hash, FORCE_HASH_DETECT},
>+ {"block-allocator", 'a', balloc, -1, 0},
>+ {"hash", 'h', hash, FORCE_HASH_DETECT, 0},
>
>- {"resize", 'r', 0, -1},
>- {"attrs", 0, 0, REISERFS_ATTRS},
>- {NULL, 0, 0, 0}
>+ {"resize", 'r', 0, -1, 0},
>+ {"attrs", 0, 0, REISERFS_ATTRS, 1},
>+ {NULL, 0, 0, 0, 0}
> };
>
> *blocks = 0;
>@@ -578,9 +594,6 @@
> /* use default configuration: create tails, journaling on, no
> conversion to newest format */
> return 1;
>- else
>- /* Drop defaults to zeroes */
>- *mount_options = 0;
>
> for (pos = options; pos; ) {
> c = reiserfs_getopt (s, &pos, opts, &arg, mount_options);
>@@ -634,26 +647,26 @@
> struct reiserfs_super_block * rs;
> struct reiserfs_transaction_handle th ;
> unsigned long blocks;
>- unsigned long mount_options = 0;
>+ unsigned long mount_options = s->u.reiserfs_sb.s_mount_opt;
>+ unsigned long safe_mask = 0;
>
> rs = SB_DISK_SUPER_BLOCK (s);
>
> if (!reiserfs_parse_options(s, data, &mount_options, &blocks))
> return 0;
>
>-#define SET_OPT( opt, bits, super ) \
>- if( ( bits ) & ( 1 << ( opt ) ) ) \
>- ( super ) -> u.reiserfs_sb.s_mount_opt |= ( 1 << ( opt ) )
>-
>- /* set options in the super-block bitmask */
>- SET_OPT( REISERFS_SMALLTAIL, mount_options, s );
>- SET_OPT( REISERFS_LARGETAIL, mount_options, s );
>- SET_OPT( REISERFS_NO_BORDER, mount_options, s );
>- SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s );
>- SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s );
>- SET_OPT( REISERFS_TEST4, mount_options, s );
>- SET_OPT( REISERFS_ATTRS, mount_options, s );
>-#undef SET_OPT
>+ /* Add options that are safe here */
>+ safe_mask |= 1 << REISERFS_SMALLTAIL;
>+ safe_mask |= 1 << REISERFS_LARGETAIL;
>+ safe_mask |= 1 << REISERFS_NO_BORDER;
>+ safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;
>+ safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
>+ safe_mask |= 1 << REISERFS_TEST4;
>+ safe_mask |= 1 << REISERFS_ATTRS;
>+
>+ /* Update the bitmask, taking care to keep
>+ * the bits we're not allowed to change here */
>+ s->u.reiserfs_sb.s_mount_opt = (s->u.reiserfs_sb.s_mount_opt & ~safe_mask) | (mount_options & safe_mask);
>
> handle_attrs( s );
>
>
>
--
Hans
next prev parent reply other threads:[~2003-02-26 21:10 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-02-26 20:42 Getopt improvements Jeff Mahoney
2003-02-26 21:10 ` Hans Reiser [this message]
2003-02-27 6:25 ` Oleg Drokin
2003-02-27 15:39 ` Jeff Mahoney
2003-02-27 16:25 ` Oleg Drokin
2003-02-27 20:20 ` Hans Reiser
2003-02-27 21:35 ` Jeff Mahoney
2003-02-27 22:35 ` Hans Reiser
2003-02-28 0:15 ` Jeff Mahoney
2003-02-28 0:22 ` Anders Widman
2003-02-28 7:47 ` Oleg Drokin
2003-02-28 7:04 ` Oleg Drokin
[not found] ` <3E5F634D.8060901@suse.com>
2003-02-28 13:54 ` Oleg Drokin
2003-02-28 7:01 ` Oleg Drokin
2003-02-28 12:04 ` Hans Reiser
2003-02-28 12:41 ` Oleg Drokin
2003-02-28 12:52 ` Hans Reiser
2003-02-28 13:15 ` Oleg Drokin
2003-02-28 13:26 ` Jeff Mahoney
2003-02-28 15:30 ` Jeff Mahoney
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=3E5D2D5E.5090400@namesys.com \
--to=reiser@namesys.com \
--cc=edward@namesys.com \
--cc=jeffm@suse.com \
--cc=reiserfs-list@namesys.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.