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