]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: use optlist to set/get options in mount context
authorKarel Zak <kzak@redhat.com>
Tue, 28 Jun 2022 11:55:47 +0000 (13:55 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 3 Jan 2023 11:53:12 +0000 (12:53 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context.c

index 152704719fa3331f9fae90fb5b8e0cb3d0f8fd55..e3bcc495fc6945cac98a7fd24ba4182a291ec87c 100644 (file)
@@ -102,6 +102,7 @@ void mnt_free_context(struct libmnt_context *cxt)
        mnt_unref_cache(cxt->cache);
        mnt_unref_fs(cxt->fs);
        mnt_unref_fs(cxt->fs_template);
+       mnt_unref_optlist(cxt->optlist);
 
        mnt_context_clear_loopdev(cxt);
        mnt_free_lock(cxt->lock);
@@ -1098,6 +1099,14 @@ const char *mnt_context_get_fstype(struct libmnt_context *cxt)
        return mnt_fs_get_fstype(mnt_context_get_fs(cxt));
 }
 
+struct libmnt_optlist *mnt_context_get_optlist(struct libmnt_context *cxt)
+{
+       if (!cxt)
+               return NULL;
+
+       return cxt->optlist ? : (cxt->optlist = mnt_new_optlist());
+}
+
 /**
  * mnt_context_set_options:
  * @cxt: mount context
@@ -1110,7 +1119,11 @@ const char *mnt_context_get_fstype(struct libmnt_context *cxt)
  */
 int mnt_context_set_options(struct libmnt_context *cxt, const char *optstr)
 {
-       return mnt_fs_set_options(mnt_context_get_fs(cxt), optstr);
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
+
+       if (!ls)
+               return -ENOMEM;
+       return mnt_optlist_set_optstr(ls, optstr, NULL);
 }
 
 /**
@@ -1122,25 +1135,36 @@ int mnt_context_set_options(struct libmnt_context *cxt, const char *optstr)
  */
 int mnt_context_append_options(struct libmnt_context *cxt, const char *optstr)
 {
-       return mnt_fs_append_options(mnt_context_get_fs(cxt), optstr);
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
+
+       if (!ls)
+               return -ENOMEM;
+       return mnt_optlist_append_optstr(ls, optstr, NULL);
 }
 
 /**
  * mnt_context_get_options:
  * @cxt: mount context
  *
- * This function returns mount options set by mnt_context_set_options() or
- * mnt_context_append_options().
+ * This function returns mount options set by mnt_context_set_options(),
+ * mnt_context_append_options() or mnt_context_set_mflags();
  *
- * Note that *after* mnt_context_prepare_mount(), the mount options string
- * may also include options set by mnt_context_set_mflags() or other options
- * generated by this library.
+ * Before v2.39 this function ignored options specified by flags (see
+ * mnt_context_set_mflags()) before mnt_context_prepare_mount() call. Now this
+ * function always returns all mount options.
  *
  * Returns: pointer or NULL
  */
 const char *mnt_context_get_options(struct libmnt_context *cxt)
 {
-       return mnt_fs_get_options(mnt_context_get_fs(cxt));
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
+       const char *str = NULL;
+
+       if (!ls)
+               return NULL;
+
+       mnt_optlist_get_optstr(ls, &str, NULL);
+       return str;
 }
 
 /**
@@ -1635,41 +1659,24 @@ struct libmnt_lock *mnt_context_get_lock(struct libmnt_context *cxt)
  *
  * Sets mount flags (see mount(2) man page).
  *
- * Note that mount context can be used to define mount options by mount flags. It
- * means you can for example use
- *
- *     mnt_context_set_mflags(cxt, MS_NOEXEC | MS_NOSUID);
- *
- * rather than
- *
- *     mnt_context_set_options(cxt, "noexec,nosuid");
- *
- * both of these calls have the same effect.
+ * Note that order of mount options (strings) and flags matter if you mix
+ * mnt_context_append_options() and mnt_context_set_mflags().
  *
- * Be careful if you want to use MS_REC flag -- in this case the bit is applied
- * to all bind/slave/etc. options. If you want to mix more propadation flags
- * and/or bind operations than it's better to specify mount options by
- * strings.
+ * Be careful if use MS_REC flag -- this is flags is generic for
+ * all mask. In this case is better to use options string where
+ * mount options are independent and nothign is applied to all options.
  *
  * Returns: 0 on success, negative number in case of error.
  */
 int mnt_context_set_mflags(struct libmnt_context *cxt, unsigned long flags)
 {
-       if (!cxt)
-               return -EINVAL;
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
 
-       cxt->mountflags = flags;
+       if (!ls)
+               return -ENOMEM;
 
-       if ((cxt->flags & MNT_FL_MOUNTOPTS_FIXED) && cxt->fs)
-               /*
-                * the final mount options are already generated, refresh...
-                */
-               return mnt_optstr_apply_flags(
-                               &cxt->fs->vfs_optstr,
-                               cxt->mountflags,
+       return mnt_optlist_set_flags(ls, flags,
                                mnt_get_builtin_optmap(MNT_LINUX_MAP));
-
-       return 0;
 }
 
 /**
@@ -1684,34 +1691,13 @@ int mnt_context_set_mflags(struct libmnt_context *cxt, unsigned long flags)
  */
 int mnt_context_get_mflags(struct libmnt_context *cxt, unsigned long *flags)
 {
-       int rc = 0;
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
 
-       if (!cxt || !flags)
-               return -EINVAL;
-
-       *flags = 0;
-
-       if (cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)
-               /*
-                * Mount options already merged to the flags
-                */
-               *flags |= cxt->orig_mountflags;
-       else {
-               /*
-                * Mount options not yet processed by library, generate the
-                * flags on-the fly
-                */
-               if (cxt->fs) {
-                       const char *o = mnt_fs_get_options(cxt->fs);
+       if (!ls)
+               return -ENOMEM;
 
-                       if (o)
-                               rc = mnt_optstr_get_flags(o, flags,
-                                           mnt_get_builtin_optmap(MNT_LINUX_MAP));
-               }
-               /* Add flags defined by mnt_context_set_mflags */
-               *flags |= cxt->mountflags;
-       }
-       return rc;
+       return mnt_optlist_get_flags(ls, flags,
+                               mnt_get_builtin_optmap(MNT_LINUX_MAP));
 }
 
 /**
@@ -1727,10 +1713,13 @@ int mnt_context_get_mflags(struct libmnt_context *cxt, unsigned long *flags)
  */
 int mnt_context_set_user_mflags(struct libmnt_context *cxt, unsigned long flags)
 {
-       if (!cxt)
-               return -EINVAL;
-       cxt->user_mountflags = flags;
-       return 0;
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
+
+       if (!ls)
+               return -ENOMEM;
+
+       return mnt_optlist_set_flags(ls, flags,
+                               mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
 }
 
 /**
@@ -1745,21 +1734,13 @@ int mnt_context_set_user_mflags(struct libmnt_context *cxt, unsigned long flags)
  */
 int mnt_context_get_user_mflags(struct libmnt_context *cxt, unsigned long *flags)
 {
-       int rc = 0;
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
 
-       if (!cxt || !flags)
-               return -EINVAL;
+       if (!ls)
+               return -ENOMEM;
 
-       *flags = 0;
-       if (!(cxt->flags & MNT_FL_MOUNTFLAGS_MERGED) && cxt->fs) {
-               const char *o = mnt_fs_get_user_options(cxt->fs);
-               if (o)
-                       rc = mnt_optstr_get_flags(o, flags,
+       return mnt_optlist_get_flags(ls, flags,
                                mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
-       }
-       if (!rc)
-               *flags |= cxt->user_mountflags;
-       return rc;
 }
 
 /**
@@ -2075,43 +2056,19 @@ int mnt_context_prepare_helper(struct libmnt_context *cxt, const char *name,
        return rc;
 }
 
-/*
- * Create cxt->mountflags from options and already defined flags. Note that the
- * flags may be later modified, the original is stored in cxt->orig_mountflags.
- */
+/* stop differentiate between options defined by flags and strings */
 int mnt_context_merge_mflags(struct libmnt_context *cxt)
 {
-       unsigned long fl = 0;
-       int rc;
-
-       assert(cxt);
+       struct libmnt_optlist *ls = mnt_context_get_optlist(cxt);
 
-       DBG(CXT, ul_debugobj(cxt, "merging mount flags"));
-
-       rc = mnt_context_get_mflags(cxt, &fl);
-       if (rc)
-               return rc;
-       cxt->orig_mountflags = cxt->mountflags = fl;
-
-       fl = 0;
-       rc = mnt_context_get_user_mflags(cxt, &fl);
-       if (rc)
-               return rc;
-       cxt->user_mountflags = fl;
-
-       DBG(CXT, ul_debugobj(cxt, "final flags: VFS=%08lx user=%08lx",
-                       cxt->mountflags, cxt->user_mountflags));
+       if (!ls)
+               return -ENOMEM;
 
+       /* TODO: optlist returns always flags as merged, so
+        * MNT_FL_MOUNTFLAGS_MERGED is unncessary anymore
+        */
        cxt->flags |= MNT_FL_MOUNTFLAGS_MERGED;
-
-       if (cxt->mountflags & MS_PROPAGATION) {
-               unsigned long rest = cxt->mountflags & ~MS_PROPAGATION;
-
-               if (rest == 0 || rest == MS_SILENT)
-                       cxt->is_propagation_only = 1;
-       }
-
-       return 0;
+       return mnt_optlist_merge_opts(ls);
 }
 
 /*