]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: minimize utimensat() write test usage
authorKarel Zak <kzak@redhat.com>
Thu, 16 Nov 2017 11:16:09 +0000 (12:16 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 16 Nov 2017 11:16:09 +0000 (12:16 +0100)
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 <dmjacobsen@lbl.gov>
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context_mount.c
libmount/src/utils.c

index 79322c061c3a2e2e8423a6abbe91fb247f61e4fb..139fb5a287fb257f83c5160984fa0e222ce7d649 100644 (file)
@@ -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
 
index 5db5494d3adb7af2a97b01a0dab7b6e6b73f9f8c..56cdc206dd135c168aed0e742d710d862d27916d 100644 (file)
@@ -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 */