Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > c2e605cb8e2a4bbe705cc43012a1cdbb > files > 16

util-linux-ng-2.17.2-10.fc13.src.rpm

diff -up util-linux-ng-2.17.2/mount/mount.c.kzak util-linux-ng-2.17.2/mount/mount.c
--- util-linux-ng-2.17.2/mount/mount.c.kzak	2010-03-22 09:10:56.000000000 +0100
+++ util-linux-ng-2.17.2/mount/mount.c	2010-07-29 16:15:28.000000000 +0200
@@ -1090,7 +1090,8 @@ loop_check(const char **spec, const char
       if (verbose)
 	printf(_("mount: skipping the setup of a loop device\n"));
     } else {
-      int loop_opts = SETLOOP_AUTOCLEAR; /* always attempt autoclear */
+      /* use autoclear loopdev on system without regular mtab only */
+      int loop_opts = mtab_is_writable() ? 0 : SETLOOP_AUTOCLEAR;
       int res;
 
       if (*flags & MS_RDONLY)
@@ -1759,6 +1760,50 @@ mounted (const char *spec0, const char *
 	return ret;
 }
 
+/* returns 0 if not mounted, 1 if mounted and -1 in case of error */
+static int
+is_fstab_entry_mounted(struct mntentchn *mc, int verbose)
+{
+	struct stat st;
+
+	if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
+		goto yes;
+
+	/* extra care for loop devices */
+	if ((strstr(mc->m.mnt_opts, "loop=") ||
+	     (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode)))) {
+
+		char *p = strstr(mc->m.mnt_opts, "offset=");
+		uintmax_t offset = 0;
+
+		if (p && *(p + 7)) {
+			char *end = NULL;
+
+			p += 7;
+			errno = 0;
+			offset = strtoumax(p, &end, 0);
+
+			if (end == p || (errno != 0 &&
+			    (offset == UINTMAX_MAX || offset == 0))) {
+				if (verbose)
+					printf(_("mount: ignore %s "
+						"(unparsable offset= option)\n"),
+						mc->m.mnt_fsname);
+				return -1;
+			}
+		}
+		if (is_mounted_same_loopfile(mc->m.mnt_dir, mc->m.mnt_fsname, offset))
+			goto yes;
+	}
+
+	return 0;
+yes:
+	if (verbose)
+		printf(_("mount: %s already mounted on %s\n"),
+			       mc->m.mnt_fsname, mc->m.mnt_dir);
+	return 1;
+}
+
 /* avoid using stat() on things we are not going to mount anyway.. */
 static int
 has_noauto (const char *opts) {
@@ -1804,16 +1849,8 @@ do_mount_all (char *types, char *options
 		if (matching_type (mc->m.mnt_type, types)
 		    && matching_opts (mc->m.mnt_opts, test_opts)
 		    && !streq (mc->m.mnt_dir, "/")
-		    && !streq (mc->m.mnt_dir, "root")) {
-
-			if (mounted (mc->m.mnt_fsname, mc->m.mnt_dir)) {
-				if (verbose)
-					printf(_("mount: %s already mounted "
-						 "on %s\n"),
-					       mc->m.mnt_fsname,
-					       mc->m.mnt_dir);
-				continue;
-			}
+		    && !streq (mc->m.mnt_dir, "root")
+		    && !is_fstab_entry_mounted(mc, verbose)) {
 
 			mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));
 			*mtmp = *mc;