From: Karel Zak Date: Thu, 16 Nov 2017 11:16:09 +0000 (+0100) Subject: libmount: minimize utimensat() write test usage X-Git-Tag: v2.32-rc1~201 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=42ee788268880e5dd3402f2179242cdb361ffe20;p=thirdparty%2Futil-linux.git libmount: minimize utimensat() write test usage utimensat() is pretty expensive when mounting parallel filesystems from the same source. It's possible to ignore all this if mtab is not writable. Note that this change is irrelevant for default util-linux builds where all around mtab is already disabled since v2.30 (commit 89958178f6d6ebe0944d423feaea66be521fff43). This change is relevant only for users who still use --enable-libmount-support-mtab. Reported-by: Douglas Jacobsen Signed-off-by: Karel Zak --- diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 79322c061c..139fb5a287 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -998,7 +998,13 @@ int mnt_context_do_mount(struct libmnt_context *cxt) #ifdef USE_LIBMOUNT_SUPPORT_MTAB if (mnt_context_get_status(cxt) && !mnt_context_is_fake(cxt) - && !cxt->helper) { + && !cxt->helper + && mnt_context_mtab_writable(cxt)) { + + int is_rdonly = -1; + + DBG(CXT, ul_debugobj(cxt, "checking for RDONLY mismatch")); + /* * Mounted by mount(2), do some post-mount checks * @@ -1007,11 +1013,13 @@ int mnt_context_do_mount(struct libmnt_context *cxt) * avoid 'ro' in mtab and 'rw' in /proc/mounts. */ if ((cxt->mountflags & MS_BIND) - && (cxt->mountflags & MS_RDONLY) - && !mnt_is_readonly(mnt_context_get_target(cxt))) + && (cxt->mountflags & MS_RDONLY)) { - mnt_context_set_mflags(cxt, - cxt->mountflags & ~MS_RDONLY); + if (is_rdonly < 0) + is_rdonly = mnt_is_readonly(mnt_context_get_target(cxt)); + if (!is_rdonly) + mnt_context_set_mflags(cxt, cxt->mountflags & ~MS_RDONLY); + } /* Kernel can silently add MS_RDONLY flag when mounting file @@ -1019,11 +1027,13 @@ int mnt_context_do_mount(struct libmnt_context *cxt) * 'ro' in /proc/mounts and 'rw' in mtab. */ if (!(cxt->mountflags & (MS_RDONLY | MS_MOVE)) - && !mnt_context_propagation_only(cxt) - && mnt_is_readonly(mnt_context_get_target(cxt))) + && !mnt_context_propagation_only(cxt)) { - mnt_context_set_mflags(cxt, - cxt->mountflags | MS_RDONLY); + if (is_rdonly < 0) + is_rdonly = mnt_is_readonly(mnt_context_get_target(cxt)); + if (is_rdonly) + mnt_context_set_mflags(cxt, cxt->mountflags | MS_RDONLY); + } } #endif diff --git a/libmount/src/utils.c b/libmount/src/utils.c index 5db5494d3a..56cdc206dd 100644 --- a/libmount/src/utils.c +++ b/libmount/src/utils.c @@ -216,6 +216,8 @@ int mnt_is_readonly(const char *path) { struct timespec times[2]; + DBG(UTILS, ul_debug(" doing utimensat() based write test")); + times[0].tv_nsec = UTIME_NOW; /* atime */ times[1].tv_nsec = UTIME_OMIT; /* mtime */