From c919d561adaf152d9b8834475539e2366c8aa484 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 1 Oct 2015 18:50:06 +0200 Subject: [PATCH] umount: always use umount2 syscall with specified flags Make umount -f more compatible with util-linux 2.22.2. Before: * 'umount -f': calls umount syscall, if it fails calls umount2 with 'MNT_FORCE' * 'mount -f -l': calls umount syscall, if it fails calls umount2 with 'MNT_LAZY'. 'MNT_FORCE' dropped After: * 'umount -f': calls umount2 syscall with 'MNT_FORCE' * 'mount -f -l': calls umount2 syscall with 'MNT_LAZY' and 'MNT_FORCE' function old new delta umount 45 - -45 umount_main 610 555 -55 Signed-off-by: Anton Bondarenko Signed-off-by: Denys Vlasenko --- util-linux/umount.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/util-linux/umount.c b/util-linux/umount.c index 4c2e8821e..c6c7441b8 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c @@ -81,8 +81,13 @@ int umount_main(int argc UNUSED_PARAM, char **argv) argv += optind; // MNT_FORCE and MNT_DETACH (from linux/fs.h) must match - // OPT_FORCE and OPT_LAZY, otherwise this trick won't work: - doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY)); + // OPT_FORCE and OPT_LAZY. + { + typedef char bug[ + (OPT_FORCE != MNT_FORCE || OPT_LAZY != MNT_DETACH) ? -1 : 1 + ]; + } + doForce = opt & (OPT_FORCE|OPT_LAZY); /* Get a list of mount points from mtab. We read them all in now mostly * for umount -a (so we don't have to worry about the list changing while @@ -147,11 +152,18 @@ int umount_main(int argc UNUSED_PARAM, char **argv) // umount the directory even if we were given the block device. if (m) zapit = m->dir; +// umount from util-linux 2.22.2 does not do this: +// umount -f uses umount2(MNT_FORCE) immediately, +// not trying umount() first. +// (Strangely, umount -fl ignores -f: it is equivalent to umount -l. +// We do pass both flags in this case) +#if 0 // Let's ask the thing nicely to unmount. curstat = umount(zapit); - // Force the unmount, if necessary. + // Unmount with force and/or lazy flags, if necessary. if (curstat && doForce) +#endif curstat = umount2(zapit, doForce); // If still can't umount, maybe remount read-only? @@ -168,7 +180,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) bb_error_msg(msg, m->device); } else { status = EXIT_FAILURE; - bb_perror_msg("can't %sumount %s", (doForce ? "forcibly " : ""), zapit); + bb_perror_msg("can't unmount %s", zapit); } } else { // De-allocate the loop device. This ioctl should be ignored on