From: Karel Zak Date: Fri, 27 Mar 2020 10:10:26 +0000 (+0100) Subject: libmount: (umount) FS lookup refactoring X-Git-Tag: v2.36-rc1~164 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ce77c625a2e87c021a87d306a66ec1f3942d430;p=thirdparty%2Futil-linux.git libmount: (umount) FS lookup refactoring Let's split lookup to more function to make it easy to add another lookup method. Signed-off-by: Karel Zak --- diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c index db6c432d06..642212fda0 100644 --- a/libmount/src/context_umount.c +++ b/libmount/src/context_umount.c @@ -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