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);
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
*/
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);
}
/**
*/
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;
}
/**
*
* 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;
}
/**
*/
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));
}
/**
*/
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));
}
/**
*/
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;
}
/**
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);
}
/*