From e61d02d2777549db389d2db29ece93983127a8c6 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 23 Sep 2024 16:34:52 +0200 Subject: [PATCH] libmount: improve how library generates fs->optstr * add missing STATMOUNT_* items * reuse merging code Signed-off-by: Karel Zak --- libmount/src/fs.c | 61 +++++++++++++++++++------------------ libmount/src/fs_statmount.c | 23 +++++++------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/libmount/src/fs.c b/libmount/src/fs.c index 230448f7c..323b74d7a 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -822,18 +822,8 @@ int mnt_fs_set_fstype(struct libmnt_fs *fs, const char *fstype) } /* - * Merges @vfs and @fs options strings into a new string. - * This function cares about 'ro/rw' options. The 'ro' is - * always used if @vfs or @fs is read-only. - * For example: - * - * mnt_merge_optstr("rw,noexec", "ro,journal=update") - * - * returns: "ro,noexec,journal=update" - * - * mnt_merge_optstr("rw,noexec", "rw,journal=update") - * - * returns: "rw,noexec,journal=update" + * Merges @vfs and @fs options strings into a new string. This function cares + * about 'ro/rw' options. The 'ro' is always used if @vfs or @fs is read-only. */ static char *merge_optstr(const char *vfs, const char *fs) { @@ -875,6 +865,25 @@ static char *merge_optstr(const char *vfs, const char *fs) return res; } +static char *fs_strdup_options(struct libmnt_fs *fs) +{ + char *res; + + errno = 0; + if (fs->optstr) + return strdup(fs->optstr); + + res = merge_optstr(fs->vfs_optstr, fs->fs_optstr); + if (!res && errno) + return NULL; + if (fs->user_optstr && + mnt_optstr_append_option(&res, fs->user_optstr, NULL)) { + free(res); + res = NULL; + } + return res; +} + /** * mnt_fs_strdup_options: * @fs: fstab/mtab/mountinfo entry pointer @@ -886,29 +895,17 @@ static char *merge_optstr(const char *vfs, const char *fs) */ char *mnt_fs_strdup_options(struct libmnt_fs *fs) { - char *res; - if (!fs) return NULL; if (fs->optlist) sync_opts_from_optlist(fs, fs->optlist); #ifdef HAVE_STATMOUNT_API else - mnt_fs_try_statmount(fs, optstr, STATMOUNT_SB_BASIC | STATMOUNT_MNT_BASIC); + mnt_fs_try_statmount(fs, optstr, STATMOUNT_SB_BASIC + | STATMOUNT_MNT_BASIC | STATMOUNT_MNT_OPTS); #endif - errno = 0; - if (fs->optstr) - return strdup(fs->optstr); + return fs_strdup_options(fs); - res = merge_optstr(fs->vfs_optstr, fs->fs_optstr); - if (!res && errno) - return NULL; - if (fs->user_optstr && - mnt_optstr_append_option(&res, fs->user_optstr, NULL)) { - free(res); - res = NULL; - } - return res; } /** @@ -924,8 +921,12 @@ const char *mnt_fs_get_options(struct libmnt_fs *fs) if (fs->optlist) sync_opts_from_optlist(fs, fs->optlist); #ifdef HAVE_STATMOUNT_API - else - mnt_fs_try_statmount(fs, optstr, STATMOUNT_SB_BASIC | STATMOUNT_MNT_BASIC); + else { + mnt_fs_try_statmount(fs, optstr, STATMOUNT_SB_BASIC + | STATMOUNT_MNT_BASIC | STATMOUNT_MNT_OPTS); + if (!fs->optstr) + fs->optstr = fs_strdup_options(fs); + } #endif return fs->optstr; } @@ -1098,7 +1099,7 @@ const char *mnt_fs_get_fs_options(struct libmnt_fs *fs) sync_opts_from_optlist(fs, fs->optlist); #ifdef HAVE_STATMOUNT_API else - mnt_fs_try_statmount(fs, fs_optstr, STATMOUNT_SB_BASIC); + mnt_fs_try_statmount(fs, fs_optstr, STATMOUNT_SB_BASIC | STATMOUNT_MNT_OPTS); #endif return fs->fs_optstr; } diff --git a/libmount/src/fs_statmount.c b/libmount/src/fs_statmount.c index d331e2476..8f05a45fd 100644 --- a/libmount/src/fs_statmount.c +++ b/libmount/src/fs_statmount.c @@ -122,8 +122,10 @@ int mnt_statmnt_disable_fetching(struct libmnt_statmnt *sm, int disable) old = sm->disabled; sm->disabled = disable ? 1 : 0; + /* DBG(STATMNT, ul_debugobj(sm, "statmount() %s", sm->disabled ? "off" : "on")); + */ return old; } @@ -179,13 +181,11 @@ static inline const char *sm_str(struct ul_statmount *sm, uint32_t offset) static int apply_statmount(struct libmnt_fs *fs, struct ul_statmount *sm) { - int rc = 0, merge = 0; + int rc = 0; if (!sm || !sm->size || !fs) return -EINVAL; - merge = !fs->vfs_optstr || fs->fs_optstr; - if ((sm->mask & STATMOUNT_FS_TYPE) && !fs->fstype) rc = mnt_fs_set_fstype(fs, sm_str(sm, sm->fs_type)); @@ -231,15 +231,19 @@ static int apply_statmount(struct libmnt_fs *fs, struct ul_statmount *sm) rc = mnt_optstr_append_option(&fs->vfs_optstr, "relatime", NULL); break; } - + free(fs->optstr); + fs->optstr = NULL; } } if (!rc && (sm->mask & STATMOUNT_MNT_NS_ID) && !fs->ns_id) fs->ns_id = sm->mnt_ns_id; - if (!rc && (sm->mask & STATMOUNT_MNT_OPTS) && !fs->fs_optstr) + if (!rc && (sm->mask & STATMOUNT_MNT_OPTS) && !fs->fs_optstr) { fs->fs_optstr = unmangle(sm_str(sm, sm->mnt_opts), NULL); + free(fs->optstr); + fs->optstr = NULL; + } if (!rc && (sm->mask & STATMOUNT_SB_BASIC)) { if (!fs->devno) @@ -253,16 +257,11 @@ static int apply_statmount(struct libmnt_fs *fs, struct ul_statmount *sm) rc = mnt_optstr_append_option(&fs->fs_optstr, "dirsync", NULL); if (!rc && (sm->sb_flags & SB_LAZYTIME)) rc = mnt_optstr_append_option(&fs->fs_optstr, "lazytime", NULL); + free(fs->optstr); + fs->optstr = NULL; } } - if (!rc && merge) { - free(fs->optstr); - - /* merge VFS and FS options to one string (we do the same in mountinfo parser) */ - fs->optstr = mnt_fs_strdup_options(fs); - } - fs->flags |= MNT_FS_KERNEL; return rc; -- 2.47.2