]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: (umount) FS lookup refactoring
authorKarel Zak <kzak@redhat.com>
Fri, 27 Mar 2020 10:10:26 +0000 (11:10 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 27 Mar 2020 10:10:26 +0000 (11:10 +0100)
Let's split lookup to more function to make it easy to add another
lookup method.

Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context_umount.c

index db6c432d067b3d808fbb7fa3c9ab9627e8d2aa6c..642212fda0aa6cf687eda9eeb755e16d08f2bd81 100644 (file)
@@ -226,28 +226,16 @@ static int has_utab_entry(struct libmnt_context *cxt, const char *target)
 
        if (!cache)
                free(cn);
-
        return rc;
 }
 
-/* this is umount replacement to mnt_context_apply_fstab(), use
- * mnt_context_tab_applied() to check result.
- */
-static int lookup_umount_fs(struct libmnt_context *cxt)
+/* returns: 1 not found; <0 on error; 1 success */
+static int lookup_umount_fs_by_statfs(struct libmnt_context *cxt, const char *tgt)
 {
-       const char *tgt;
        struct stat st;
-       struct libmnt_fs *fs = NULL;
-       int rc = 0;
-
-       assert(cxt);
-       assert(cxt->fs);
+       const char *type;
 
-       tgt = mnt_fs_get_target(cxt->fs);
-       if (!tgt) {
-               DBG(CXT, ul_debugobj(cxt, "umount: undefined target"));
-               return -EINVAL;
-       }
+       DBG(CXT, ul_debugobj(cxt, " lookup by statfs"));
 
        /*
         * Let's try to avoid mountinfo usage at all to minimize performance
@@ -261,53 +249,56 @@ static int lookup_umount_fs(struct libmnt_context *cxt)
         * umounts as target is probably unreachable NFS, also for --detach-loop
         * as this additionally needs to know the name of the loop device).
         */
-       if (!mnt_context_is_restricted(cxt)
-           && *tgt == '/'
-           && !(cxt->flags & MNT_FL_HELPER)
-           && !mnt_context_mtab_writable(cxt)
-           && !mnt_context_is_force(cxt)
-           && !mnt_context_is_lazy(cxt)
-           && !mnt_context_is_nocanonicalize(cxt)
-           && !mnt_context_is_loopdel(cxt)
-           && mnt_stat_mountpoint(tgt, &st) == 0 && S_ISDIR(st.st_mode)
-           && !has_utab_entry(cxt, tgt)) {
-
-               const char *type = mnt_fs_get_fstype(cxt->fs);
-
-               DBG(CXT, ul_debugobj(cxt, "umount: disable mtab"));
-
-               /* !mnt_context_mtab_writable(cxt) && has_utab_entry() verified that there
-                * is no stuff in utab, so disable all mtab/utab related actions */
-               mnt_context_disable_mtab(cxt, TRUE);
-
-               if (!type) {
-                       struct statfs vfs;
-
-                       DBG(CXT, ul_debugobj(cxt, "umount: trying statfs()"));
-                       if (statfs(tgt, &vfs) == 0)
-                               type = mnt_statfs_get_fstype(&vfs);
-                       if (type) {
-                               rc = mnt_fs_set_fstype(cxt->fs, type);
-                               if (rc)
-                                       return rc;
-                       }
-               }
+       if (mnt_context_is_restricted(cxt)
+           || *tgt != '/'
+           || (cxt->flags & MNT_FL_HELPER)
+           || mnt_context_mtab_writable(cxt)
+           || mnt_context_is_force(cxt)
+           || mnt_context_is_lazy(cxt)
+           || mnt_context_is_nocanonicalize(cxt)
+           || mnt_context_is_loopdel(cxt)
+           || mnt_stat_mountpoint(tgt, &st) != 0 || !S_ISDIR(st.st_mode)
+           || has_utab_entry(cxt, tgt))
+               return 1; /* not found */
+
+       type = mnt_fs_get_fstype(cxt->fs);
+
+       DBG(CXT, ul_debugobj(cxt, "  umount: disabling mtab"));
+       mnt_context_disable_mtab(cxt, TRUE);
+
+       if (!type) {
+               struct statfs vfs;
+
+               DBG(CXT, ul_debugobj(cxt, "  trying statfs()"));
+               if (statfs(tgt, &vfs) == 0)
+                       type = mnt_statfs_get_fstype(&vfs);
                if (type) {
-                       DBG(CXT, ul_debugobj(cxt,
-                               "umount: mountinfo unnecessary [type=%s]", type));
-                       return 0;
+                       int rc = mnt_fs_set_fstype(cxt->fs, type);
+                       if (rc)
+                               return rc;
                }
        }
+       if (type) {
+               DBG(CXT, ul_debugobj(cxt,
+                       "  mountinfo unnecessary [type=%s]", type));
+               return 0;
+       }
+
+       return 1; /* not found */
+}
+
+/* returns: 1 not found; <0 on error; 1 success */
+static int lookup_umount_fs_by_mountinfo(struct libmnt_context *cxt, const char *tgt)
+{
+       struct libmnt_fs *fs = NULL;
+       int rc;
+
+       DBG(CXT, ul_debugobj(cxt, " lookup by mountinfo"));
 
        rc = mnt_context_find_umount_fs(cxt, tgt, &fs);
-       if (rc < 0)
+       if (rc != 0)
                return rc;
 
-       if (rc == 1 || !fs) {
-               DBG(CXT, ul_debugobj(cxt, "umount: cannot find '%s' in mtab", tgt));
-               return 0;       /* this is correct! */
-       }
-
        if (fs != cxt->fs) {
                /* copy from mtab to our FS description
                 */
@@ -315,14 +306,47 @@ static int lookup_umount_fs(struct libmnt_context *cxt)
                mnt_fs_set_target(cxt->fs, NULL);
 
                if (!mnt_copy_fs(cxt->fs, fs)) {
-                       DBG(CXT, ul_debugobj(cxt, "umount: failed to copy FS"));
+                       DBG(CXT, ul_debugobj(cxt, "  failed to copy FS"));
                        return -errno;
                }
-               DBG(CXT, ul_debugobj(cxt, "umount: mtab applied"));
+               DBG(CXT, ul_debugobj(cxt, "  mtab applied"));
        }
 
        cxt->flags |= MNT_FL_TAB_APPLIED;
-       return rc;
+       return 0;
+}
+
+/* this is umount replacement to mnt_context_apply_fstab(), use
+ * mnt_context_tab_applied() to check result.
+ */
+static int lookup_umount_fs(struct libmnt_context *cxt)
+{
+       const char *tgt;
+       int rc = 0;
+
+       assert(cxt);
+       assert(cxt->fs);
+
+       DBG(CXT, ul_debugobj(cxt, "umount: lookup FS"));
+
+       tgt = mnt_fs_get_target(cxt->fs);
+       if (!tgt) {
+               DBG(CXT, ul_debugobj(cxt, " undefined target"));
+               return -EINVAL;
+       }
+
+       /* try get fs type by statfs() */
+       rc = lookup_umount_fs_by_statfs(cxt, tgt);
+       if (rc <= 0)
+               return rc;
+
+       /* get complete fs from fs entry from mountinfo */
+       rc = lookup_umount_fs_by_mountinfo(cxt, tgt);
+       if (rc <= 0)
+               return rc;
+
+       DBG(CXT, ul_debugobj(cxt, " cannot find '%s'", tgt));
+       return 0;       /* this is correct! */
 }
 
 /* check if @devname is loopdev and if the device is associated