mount: add support for -O list. +44 bytes

Signed-off-by: Michael Abbott <michael@araneidae.co.uk>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Michael Abbott
2009-12-04 03:33:07 +01:00
committed by Denys Vlasenko
parent 6dc0ace109
commit 6b5accbfc1

View File

@ -1760,43 +1760,61 @@ static int singlemount(struct mntent *mp, int ignore_busy)
return rc; return rc;
} }
/* -O support // -O support
* Unlike -t, -O should interpret "no" prefix differently: // -O interprets a list of filter options which select whether a mount
* -t noa,b,c = -t no(a,b,c) = mount all except fs'es with types a,b, and c // point will be mounted: only mounts with options matching *all* filtering
* -O noa,b,c = -O noa,b,c = mount all with without option a, // options will be selected.
* or with option b or c. // By default each -O filter option must be present in the list of mount
* But for now we do not support -O a,b,c at all (only -O a). // options, but if it is prefixed by "no" then it must be absent.
* // For example,
* Another difference from -t support (match_fstype) is that // -O a,nob,c matches -o a,c but fails to match -o a,b,c
* we need to examine the _list_ of options in fsopt, not just a string. // (and also fails to match -o a because -o c is absent).
*/ //
static int match_opt(const char *fs_opt, const char *O_opt) // 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_in, const char *O_opt)
{ {
int match = 1;
int len;
if (!O_opt) if (!O_opt)
return match; return 1;
while (*O_opt) {
const char *fs_opt = fs_opt_in;
int O_len;
int match;
// If option begins with "no" then treat as an inverted match:
// matching is a failure
match = 0;
if (O_opt[0] == 'n' && O_opt[1] == 'o') { if (O_opt[0] == 'n' && O_opt[1] == 'o') {
match--; match = 1;
O_opt += 2; O_opt += 2;
} }
// Isolate the current O option
len = strlen(O_opt); O_len = strchrnul(O_opt, ',') - O_opt;
// Check for a match against existing options
while (1) { while (1) {
if (strncmp(fs_opt, O_opt, len) == 0 if (strncmp(fs_opt, O_opt, O_len) == 0
&& (fs_opt[len] == '\0' || fs_opt[len] == ',') && (fs_opt[O_len] == '\0' || fs_opt[O_len] == ',')
) { ) {
return match; if (match)
return 0; // "no" prefix, but option found
match = 1; // current O option found, go check next one
break;
} }
fs_opt = strchr(fs_opt, ','); fs_opt = strchr(fs_opt, ',');
if (!fs_opt) if (!fs_opt)
break; break;
fs_opt++; fs_opt++;
} }
if (match == 0)
return !match; return 0; // match wanted but not found
if (O_opt[O_len] == '\0') // end?
break;
// Step to the next O option
O_opt += O_len + 1;
}
// If we get here then everything matched
return 1;
} }
// Parse options, if necessary parse fstab/mtab, and call singlemount for // Parse options, if necessary parse fstab/mtab, and call singlemount for