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:
committed by
Denys Vlasenko
parent
6dc0ace109
commit
6b5accbfc1
@ -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
|
||||||
|
Reference in New Issue
Block a user