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;