struct libmnt_optlist *ol;
struct libmnt_opt *opt;
struct libmnt_ns *ns_old;
- struct libmnt_fs *fs;
const char *val;
int rc = 0;
#ifdef HAVE_LIBSELINUX
if (cxt->flags & MNT_FL_MOUNTOPTS_FIXED)
return 0;
- fs = cxt->fs;
-
DBG(CXT, ul_debugobj(cxt, "--> preparing options"));
ol = mnt_context_get_optlist(cxt);
}
#endif
mnt_context_call_hooks(cxt, MNT_STAGE_PREP_OPTIONS);
-
- /* For backward compatinility update context fs mount options */
- if (fs) {
- const char *p;
-
- /* All options */
- mnt_optlist_get_optstr(ol, &p, NULL, 0);
- strdup_to_struct_member(fs, optstr, p);
-
- /* FS options */
- mnt_optlist_get_optstr(ol, &p, NULL, MNT_OL_FLTR_UNKNOWN);
- strdup_to_struct_member(fs, fs_optstr, p);
-
- /* VFS options */
- mnt_optlist_get_optstr(ol, &p, cxt->map_linux, 0);
- strdup_to_struct_member(fs, vfs_optstr, p);
-
- /* Userspace options */
- mnt_optlist_get_optstr(ol, &p, cxt->map_userspace, 0);
- strdup_to_struct_member(fs, user_optstr, p);
-
- DBG(CXT, ul_debugobj(cxt, " fixed options: "
- "vfs: '%s' fs: '%s' user: '%s', optstr: '%s'",
- fs->vfs_optstr, fs->fs_optstr, fs->user_optstr, fs->optstr));
- }
-
done:
DBG(CXT, ul_debugobj(cxt, "<-- preparing options done [rc=%d]", rc));
cxt->flags |= MNT_FL_MOUNTOPTS_FIXED;
rc = mnt_context_apply_fstab(cxt);
if (!rc)
rc = mnt_context_merge_mflags(cxt);
+ if (!rc && cxt->fs && cxt->optlist)
+ rc = mnt_fs_follow_optlist(cxt->fs, cxt->optlist);
if (!rc)
rc = evaluate_permissions(cxt);
if (!rc)
DBG(FS, ul_debugobj(fs, "free [refcount=%d]", fs->refcount));
+ mnt_unref_optlist(fs->optlist);
+
mnt_reset_fs(fs);
free(fs);
}
free(fs->opt_fields);
free(fs->comment);
+ fs->opts_age = 0;
+
memset(fs, 0, sizeof(*fs));
INIT_LIST_HEAD(&fs->ents);
fs->refcount = ref;
return update_str(n, *o);
}
+static inline int sync_opts_from_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol)
+{
+ unsigned int age = mnt_optlist_get_age(ol);
+
+ if (age != fs->opts_age) {
+ const char *p;
+ int rc;
+
+ /* All options */
+ rc = mnt_optlist_get_optstr(ol, &p, NULL, 0);
+ if (!rc)
+ rc = strdup_to_struct_member(fs, optstr, p);
+
+ /* FS options */
+ if (!rc)
+ rc = mnt_optlist_get_optstr(ol, &p, NULL, MNT_OL_FLTR_UNKNOWN);
+ if (!rc)
+ rc = strdup_to_struct_member(fs, fs_optstr, p);
+
+ /* VFS options */
+ if (!rc)
+ rc = mnt_optlist_get_optstr(ol, &p, mnt_get_builtin_optmap(MNT_LINUX_MAP), 0);
+ if (!rc)
+ rc = strdup_to_struct_member(fs, vfs_optstr, p);
+
+ /* Userspace options */
+ if (!rc)
+ rc = mnt_optlist_get_optstr(ol, &p, mnt_get_builtin_optmap(MNT_USERSPACE_MAP), 0);
+ if (!rc)
+ rc = strdup_to_struct_member(fs, user_optstr, p);
+
+ if (rc) {
+ DBG(FS, ul_debugobj(fs, "sync failed [rc=%d]", rc));
+ return rc;
+ } else {
+ DBG(FS, ul_debugobj(fs, "synced: "
+ "vfs: '%s' fs: '%s' user: '%s', optstr: '%s'",
+ fs->vfs_optstr, fs->fs_optstr, fs->user_optstr, fs->optstr));
+ fs->opts_age = age;
+ }
+ }
+ return 0;
+}
+
+/* If @optlist is not NULL then @fs will read all option strings from @optlist.
+ * It means that mnt_fs_get_*_options() won't be read-only operations. */
+int mnt_fs_follow_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol)
+{
+ if (fs->optlist == ol)
+ return 0;
+
+ fs->opts_age = 0;
+ fs->optlist = ol;
+ mnt_ref_optlist(ol);
+ return 0;
+}
+
/**
* mnt_copy_fs:
* @dest: destination FS
dest->usedsize = src->usedsize;
dest->priority = src->priority;
+ dest->opts_age = src->opts_age;
+ dest->optlist = src->optlist;
+ mnt_ref_optlist(dest->optlist);
+
return dest;
err:
if (!org)
*
* Returns: copy of @fs.
*/
-struct libmnt_fs *mnt_copy_mtab_fs(const struct libmnt_fs *fs)
+struct libmnt_fs *mnt_copy_mtab_fs(struct libmnt_fs *fs)
{
struct libmnt_fs *n = mnt_new_fs();
assert(fs);
if (!n)
return NULL;
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
if (strdup_between_structs(n, fs, source))
goto err;
if (!fs)
return NULL;
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
errno = 0;
if (fs->optstr)
*/
const char *mnt_fs_get_options(struct libmnt_fs *fs)
{
+ if (fs && fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
+
return fs ? fs->optstr : NULL;
}
if (!fs)
return -EINVAL;
+ fs->opts_age = 0;
+
if (optstr) {
int rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
if (rc)
if (!optstr)
return 0;
+ fs->opts_age = 0;
+
rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
if (rc)
return rc;
if (!optstr)
return 0;
+ fs->opts_age = 0;
+
rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
if (rc)
return rc;
return rc;
}
-/*
+
+/**
* mnt_fs_get_fs_options:
* @fs: fstab/mtab/mountinfo entry pointer
*
*/
const char *mnt_fs_get_fs_options(struct libmnt_fs *fs)
{
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
+
return fs ? fs->fs_optstr : NULL;
}
*/
const char *mnt_fs_get_vfs_options(struct libmnt_fs *fs)
{
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
+
return fs ? fs->vfs_optstr : NULL;
}
*/
const char *mnt_fs_get_user_options(struct libmnt_fs *fs)
{
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
+
return fs ? fs->user_optstr : NULL;
}
if (!fs)
return -EINVAL;
+
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
+
if (fs->fs_optstr)
rc = mnt_optstr_get_option(fs->fs_optstr, name, value, valsz);
if (rc == 1 && fs->vfs_optstr)
{
if (!fs || !file)
return -EINVAL;
+
+ if (fs->optlist)
+ sync_opts_from_optlist(fs, fs->optlist);
+
fprintf(file, "------ fs:\n");
fprintf(file, "source: %s\n", mnt_fs_get_source(fs));
fprintf(file, "target: %s\n", mnt_fs_get_target(fs));
struct libmnt_table *tab;
int refcount; /* reference counter */
+
+ unsigned int opts_age; /* to sync with optlist */
+ struct libmnt_optlist *optlist;
+
int id; /* mountinfo[1]: ID */
int parent; /* mountinfo[2]: parent */
dev_t devno; /* mountinfo[3]: st_dev */
extern struct libmnt_optlist *mnt_new_optlist(void);
extern void mnt_ref_optlist(struct libmnt_optlist *ls);
extern void mnt_unref_optlist(struct libmnt_optlist *ls);
+extern unsigned int mnt_optlist_get_age(struct libmnt_optlist *ls);
extern int mnt_optlist_register_map(struct libmnt_optlist *ls, const struct libmnt_optmap *map);
extern int mnt_optlist_remove_opt(struct libmnt_optlist *ls, struct libmnt_opt *opt);
extern int mnt_optlist_remove_named(struct libmnt_optlist *ls, const char *name,
/* fs.c */
-extern struct libmnt_fs *mnt_copy_mtab_fs(const struct libmnt_fs *fs);
+extern int mnt_fs_follow_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol);
+extern struct libmnt_fs *mnt_copy_mtab_fs(struct libmnt_fs *fs);
extern int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source)
__attribute__((nonnull(1)));
extern int __mnt_fs_set_fstype_ptr(struct libmnt_fs *fs, char *fstype)