]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: improve how library generates fs->optstr
authorKarel Zak <kzak@redhat.com>
Mon, 23 Sep 2024 14:34:52 +0000 (16:34 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 8 Jan 2025 12:57:43 +0000 (13:57 +0100)
* add missing STATMOUNT_* items
* reuse merging code

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

index 230448f7ce40b6c5cb49061869d6aa6f588ab5ce..323b74d7a4695de5208fc2b17ceb32dd603e77da 100644 (file)
@@ -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;
 }
index d331e247606907e5382a838663f5f6aace539f9c..8f05a45fd21667eab0164c86bc8cb7afd74118ea 100644 (file)
@@ -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;