PATCH: mount -O list
Denys Vlasenko
vda.linux at googlemail.com
Thu Dec 3 00:59:39 UTC 2009
On Tuesday 01 December 2009 10:30, Michael Abbott wrote:
> The attached patch implements support for a list of filter options on the
> -O option.
>
> I have assumed that when
> -O a,nob,c
> is requested that this should be interpreted as requiring that both -o a
> and -o c are specified, as well as that -o b is *not* specified.
> Unfortunately the mount man page is annoyingly ambiguous on this.
Can you determine that experimentally?
> diff -ur busybox-1.15.2/util-linux/mount.c busybox-1.15.2-patched/util-linux/mount.c
> --- busybox-1.15.2/util-linux/mount.c 2009-10-08 01:59:09.000000000 +0100
> +++ busybox-1.15.2-patched/util-linux/mount.c 2009-12-01 09:19:07.000000000 +0000
> @@ -1775,42 +1775,64 @@
> }
>
> /* -O support
> - * Unlike -t, -O should interpret "no" prefix differently:
> - * -t noa,b,c = -t no(a,b,c) = mount all except fs'es with types a,b, and c
> - * -O noa,b,c = -O noa,b,c = mount all with without option a,
> - * or with option b or c.
> - * But for now we do not support -O a,b,c at all (only -O a).
> + * -O interprets a list of filter options which select whether a mount
> + * point will be mounted: only mounts with options matching *all* filtering
> + * options will be selected.
> + * By default each -O filter option must be present in the list of mount
> + * options, but if it is prefixed by "no" then it must be absent. For
> + * example,
> + * -O a,nob,c matches -o a,c but fails to match -o a,b,c
> + * (and also fails to match -o a because -o c is absent).
> *
> - * Another difference from -t support (match_fstype) is that
> - * we need to examine the _list_ of options in fsopt, not just a string.
> + * It is different from -t in that each option is matched exactly; a leading
> + * no at the beginning of one option does not negate the rest.
> */
> -static int match_opt(const char *fs_opt, const char *O_opt)
> +static int match_opt(const char *fs_opt_in, const char *O_opt)
> {
> - int match = 1;
> - int len;
> -
> if (!O_opt)
> - return match;
> -
> - if (O_opt[0] == 'n' && O_opt[1] == 'o') {
> - match--;
> - O_opt += 2;
> - }
> -
> - len = strlen(O_opt);
> - while (1) {
> - if (strncmp(fs_opt, O_opt, len) == 0
> - && (fs_opt[len] == '\0' || fs_opt[len] == ',')
> - ) {
> - return match;
> + return 1;
> + while (*O_opt)
> + {
misplaced brace
> + const char *O_comma;
> + int O_len;
> + const char *fs_opt = fs_opt_in;
> + int match = 0;
> + /* If option begins no then treat as an inverted match: matching is a
'...If options begins with "no"...'
> + * failure. */
> + if (O_opt[0] == 'n' && O_opt[1] == 'o') {
> + match = 1;
> + O_opt += 2;
> }
> - fs_opt = strchr(fs_opt, ',');
> - if (!fs_opt)
> + /* Isolate the current O option (after processing any no prefix). */
> + O_comma = strchr(O_opt, ',');
> + O_len = O_comma ? O_comma - O_opt : strlen(O_opt);
> + /* Check for a match against existing options. */
> + while (1) {
> + if (strncmp(fs_opt, O_opt, O_len) == 0
> + && (fs_opt[O_len] == '\0' || fs_opt[O_len] == ',')
> + ) {
> + if (match)
> + return 0; // no match selected, but option found
> + else {
"else" after "return" can be omitted.
> + match = 1; // option found, so try for next O option
> + break;
> + }
> + }
> + fs_opt = strchr(fs_opt, ',');
> + if (!fs_opt)
> + break;
> + fs_opt++;
> + }
> + if (match == 0)
> + return 0; // match wanted but not found
> + /* Step to the next O option. */
> + if (O_comma)
> + O_opt = O_comma + 1;
> + else
> break;
Perhaps the other way around:
if (!O_comma)
break;
O_opt = O_comma + 1;
--
vda
More information about the busybox
mailing list