[git commit master] mount: add support for -O list. +44 bytes

Denys Vlasenko vda.linux at googlemail.com
Fri Dec 4 02:33:07 UTC 2009


commit: http://git.busybox.net/busybox/commit/?id=6b5accbfc1f721c5c34b8a3bfad07a19053946d0
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Michael Abbott <michael at araneidae.co.uk>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 util-linux/mount.c |   82 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 50 insertions(+), 32 deletions(-)

diff --git a/util-linux/mount.c b/util-linux/mount.c
index d27d65f..d7ca7da 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -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;
-
-	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) {
+		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') {
+			match = 1;
+			O_opt += 2;
+		}
+		// 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++;
 		}
-		fs_opt = strchr(fs_opt, ',');
-		if (!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
-- 
1.6.3.3



More information about the busybox-cvs mailing list