- mount allows loopback devices to be mounted more than once to the same mount point --- util-linux-2.13-pre6/mount/fstab.h.twiceloop 2006-09-15 08:50:46.000000000 +0200 +++ util-linux-2.13-pre6/mount/fstab.h 2006-09-15 08:51:10.000000000 +0200 @@ -2,6 +2,7 @@ int mtab_is_writable(void); int mtab_does_not_exist(void); int is_mounted_once(const char *name); +int is_mounted_same_loopfile(const char *loopfile, const char *dir); struct mntentchn { struct mntentchn *nxt, *prev; --- util-linux-2.13-pre6/mount/mount.c.twiceloop 2006-09-15 08:50:23.000000000 +0200 +++ util-linux-2.13-pre6/mount/mount.c 2006-09-15 08:50:24.000000000 +0200 @@ -671,7 +671,7 @@ static int loop_check(const char **spec, const char **type, int *flags, - int *loop, const char **loopdev, const char **loopfile) { + int *loop, const char **loopdev, const char **loopfile, const char *dir) { int looptype; unsigned long long offset; @@ -709,6 +709,11 @@ } else { int loopro = (*flags & MS_RDONLY); + if (is_mounted_same_loopfile(*loopfile, dir)) { + error(_("mount: %s already mounted on %s"), *loopfile, dir); + return EX_FAIL; + } + if (!*loopdev || !**loopdev) *loopdev = find_unused_loop_device(); if (!*loopdev) @@ -856,7 +861,7 @@ * stale assignments of files to loop devices. Nasty when used for * encryption. */ - res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile); + res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile, node); if (res) goto out; } --- util-linux-2.13-pre6/mount/fstab.c.twiceloop 2006-09-15 08:50:23.000000000 +0200 +++ util-linux-2.13-pre6/mount/fstab.c 2006-09-15 08:50:24.000000000 +0200 @@ -254,6 +254,27 @@ return (ct == 1); } +/* + * Given the loop file LOOPFILE, and the mount point DIR, check that + * same file is already mounted on same directory + * + * Don't forget there's + * /path/loopfile /path/dir loop=/dev/loop0 + * in mtab for loop devices. + */ +int +is_mounted_same_loopfile(const char *loopfile, const char *dir) { + struct mntentchn *mc, *mc0; + int ct = 0; + + mc0 = mtab_head(); + for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev) + if (streq(mc->m.mnt_fsname, loopfile) && + streq(mc->m.mnt_dir, dir)) + ct++; + return (ct == 1); +} + /* Given the name FILE, try to find the option "loop=FILE" in mtab. */ struct mntentchn * getmntoptfile (const char *file) {