From: Karel Zak Date: Tue, 28 Jun 2022 11:55:47 +0000 (+0200) Subject: libmount: use optlist to set/get options in mount context X-Git-Tag: v2.39-rc1~323 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9a72da2c23d0bfdf8781abdf6d1da9e8dd914829;p=thirdparty%2Futil-linux.git libmount: use optlist to set/get options in mount context Signed-off-by: Karel Zak --- diff --git a/libmount/src/context.c b/libmount/src/context.c index 152704719f..e3bcc495fc 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -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); } /*