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
* 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
*/
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