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;
}
/* -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).
*
* Another difference from -t support (match_fstype) is that
* we need to examine the _list_ of options in fsopt, not just a string.
*/
static int match_opt(const char *fs_opt, const char *O_opt)
// -O support
// -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).
//
// 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)
return match;
return 1;
if (O_opt[0] == 'n' && O_opt[1] == 'o') {
match--;
O_opt += 2;
}
while (*O_opt) {
const char *fs_opt = fs_opt_in;
int O_len;
int match;
len = strlen(O_opt);
while (1) {
if (strncmp(fs_opt, O_opt, len) == 0
&& (fs_opt[len] == '\0' || fs_opt[len] == ',')
) {
return 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') {
match = 1;
O_opt += 2;
}
fs_opt = strchr(fs_opt, ',');
if (!fs_opt)
// Isolate the current O option
O_len = strchrnul(O_opt, ',') - 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" prefix, but option found
match = 1; // current O option found, go check next one
break;
}
fs_opt = strchr(fs_opt, ',');
if (!fs_opt)
break;
fs_opt++;
}
if (match == 0)
return 0; // match wanted but not found
if (O_opt[O_len] == '\0') // end?
break;
fs_opt++;
// Step to the next O option
O_opt += O_len + 1;
}
return !match;
// If we get here then everything matched
return 1;
}
// Parse options, if necessary parse fstab/mtab, and call singlemount for