]> err.no Git - util-linux/commitdiff
libmount: use separate buffer for userspace options, add mount attributes
authorKarel Zak <kzak@redhat.com>
Tue, 14 Dec 2010 22:50:55 +0000 (23:50 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Jan 2011 11:28:47 +0000 (12:28 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
21 files changed:
shlibs/mount/src/context.c
shlibs/mount/src/context_mount.c
shlibs/mount/src/context_umount.c
shlibs/mount/src/fs.c
shlibs/mount/src/mount.h.in
shlibs/mount/src/mount.sym
shlibs/mount/src/mountP.h
shlibs/mount/src/optmap.c
shlibs/mount/src/optstr.c
shlibs/mount/src/tab_parse.c
shlibs/mount/src/tab_update.c
tests/expected/libmount/tabfiles-copy
tests/expected/libmount/tabfiles-find-pair
tests/expected/libmount/tabfiles-find-source
tests/expected/libmount/tabfiles-find-target
tests/expected/libmount/tabfiles-parse-fstab
tests/expected/libmount/tabfiles-parse-fstab-broken
tests/expected/libmount/tabfiles-parse-mountinfo
tests/expected/libmount/tabfiles-parse-mtab
tests/expected/libmount/update-mtab-mount
tests/expected/libmount/update-mtab-move

index 4fe2eabf404be31194e02bbb31feb67ee8586081..59e8bd920f5dfa99171dd4741bcad1a0d258e5fc 100644 (file)
@@ -93,7 +93,8 @@ void mnt_free_context(mnt_context *cxt)
  *     mnt_context_set_fstab(cxt, NULL);
  *     mnt_context_set_cache(cxt, NULL);
  *     mnt_context_set_fstype_pattern(cxt, NULL);
- *     mnt_context_set_optstr_pattern(cxt, NULL);
+ *     mnt_context_set_options_pattern(cxt, NULL);
+ *
  *
  * to reset these stuff.
  *
@@ -358,8 +359,8 @@ int mnt_context_enable_loopdel(mnt_context *cxt, int enable)
  * overwrite the private @fs with an external instance. Note that the external
  * @fs instance is not deallocated by mnt_free_context() or mnt_reset_context().
  *
- * The @fs will be modified by mnt_context_set_{source,target,optstr,fstype}
- * functions, Ft the @fs is NULL then all current FS specific setting (source,
+ * The @fs will be modified by mnt_context_set_{source,target,options,fstype}
+ * functions, If the @fs is NULL then all current FS specific setting (source,
  * target, etc., exclude spec) is reseted.
  *
  * Returns: 0 on success, negative number in case of error.
@@ -376,6 +377,16 @@ int mnt_context_set_fs(mnt_context *cxt, mnt_fs *fs)
        return 0;
 }
 
+/**
+ * mnt_context_get_fs:
+ * @cxt: mount context
+ *
+ * The FS contains the basic description of mountpoint, fs type and so on.
+ * Note that the FS is modified by mnt_context_set_{source,target,options,fstype}
+ * functions.
+ *
+ * Returns: pointer to FS description or NULL in case of calloc() errrr.
+ */
 mnt_fs *mnt_context_get_fs(mnt_context *cxt)
 {
        if (!cxt)
@@ -429,27 +440,27 @@ int mnt_context_set_fstype(mnt_context *cxt, const char *fstype)
 }
 
 /**
- * mnt_context_set_optstr:
+ * mnt_context_set_options:
  * @cxt: mount context
- * @optstr: comma delimited mount options
+ * @options: comma delimited mount options
  *
  * Returns: 0 on success, negative number in case of error.
  */
-int mnt_context_set_optstr(mnt_context *cxt, const char *optstr)
+int mnt_context_set_options(mnt_context *cxt, const char *optstr)
 {
-       return mnt_fs_set_optstr(mnt_context_get_fs(cxt), optstr);
+       return mnt_fs_set_options(mnt_context_get_fs(cxt), optstr);
 }
 
 /**
- * mnt_context_append_optstr:
+ * mnt_context_append_options:
  * @cxt: mount context
  * @optstr: comma delimited mount options
  *
  * Returns: 0 on success, negative number in case of error.
  */
-int mnt_context_append_optstr(mnt_context *cxt, const char *optstr)
+int mnt_context_append_options(mnt_context *cxt, const char *optstr)
 {
-       return mnt_fs_append_optstr(mnt_context_get_fs(cxt), optstr);
+       return mnt_fs_append_options(mnt_context_get_fs(cxt), optstr);
 }
 
 /**
@@ -478,7 +489,7 @@ int mnt_context_set_fstype_pattern(mnt_context *cxt, const char *pattern)
 }
 
 /**
- * mnt_context_set_optstr_pattern:
+ * mnt_context_set_options_pattern:
  * @cxt: mount context
  * @pattern: options pattern (or NULL to reset the current setting)
  *
@@ -486,7 +497,7 @@ int mnt_context_set_fstype_pattern(mnt_context *cxt, const char *pattern)
  *
  * Returns: 0 on success, negative number in case of error.
  */
-int mnt_context_set_optstr_pattern(mnt_context *cxt, const char *pattern)
+int mnt_context_set_options_pattern(mnt_context *cxt, const char *pattern)
 {
        char *p = NULL;
 
@@ -693,7 +704,7 @@ mnt_lock *mnt_context_get_lock(mnt_context *cxt)
  *
  * rather than
  *
- *     mnt_context_set_optstr(cxt, "noexec,nosuid");
+ *     mnt_context_set_options(cxt, "noexec,nosuid");
  *
  * these both calls have the same effect.
  *
@@ -725,9 +736,10 @@ int mnt_context_get_mountflags(mnt_context *cxt, unsigned long *flags)
 
        *flags = 0;
        if (!(cxt->flags & MNT_FL_MOUNTFLAGS_MERGED) && cxt->fs) {
-               const char *o = mnt_fs_get_optstr(cxt->fs);
+               const char *o = mnt_fs_get_vfs_options(cxt->fs);
                if (o)
-                       rc = mnt_optstr_get_mountflags(o, flags);
+                       rc = mnt_optstr_get_flags(o, flags,
+                                   mnt_get_builtin_optmap(MNT_LINUX_MAP));
        }
        if (!rc)
                *flags |= cxt->mountflags;
@@ -769,9 +781,10 @@ int mnt_context_get_userspace_mountflags(mnt_context *cxt, unsigned long *flags)
 
        *flags = 0;
        if (!(cxt->flags & MNT_FL_MOUNTFLAGS_MERGED) && cxt->fs) {
-               const char *o = mnt_fs_get_optstr(cxt->fs);
+               const char *o = mnt_fs_get_userspace_options(cxt->fs);
                if (o)
-                       rc = mnt_optstr_get_userspace_mountflags(o, flags);
+                       rc = mnt_optstr_get_flags(o, flags,
+                               mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
        }
        if (!rc)
                *flags |= cxt->user_mountflags;
@@ -1025,6 +1038,11 @@ int mnt_context_merge_mountflags(mnt_context *cxt)
                return rc;
        cxt->mountflags = fl;
 
+       /* TODO: if cxt->fs->fs_optstr contains 'ro' then set the MS_RDONLY to
+        * mount flags, it's possible that superblock is read-only, but VFS is
+        * read-write.
+        */
+
        fl = 0;
        rc = mnt_context_get_userspace_mountflags(cxt, &fl);
        if (rc)
@@ -1172,9 +1190,16 @@ static int apply_tab(mnt_context *cxt, mnt_tab *tb, int direction)
        if (!rc && !mnt_fs_get_fstype(cxt->fs))
                rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs));
 
-       if (!rc && cxt->optsmode != MNT_OPTSMODE_IGNORE)
-               rc = mnt_fs_prepend_optstr(cxt->fs, mnt_fs_get_optstr(fs));
-
+       if (!rc && cxt->optsmode != MNT_OPTSMODE_IGNORE) {
+               rc = mnt_fs_prepend_vfs_options(cxt->fs,
+                                       mnt_fs_get_vfs_options(fs));
+               if (!rc)
+                       rc = mnt_fs_prepend_fs_options(cxt->fs,
+                                       mnt_fs_get_fs_options(fs));
+               if (!rc)
+                       rc = mnt_fs_prepend_userspace_options(cxt->fs,
+                                       mnt_fs_get_userspace_options(fs));
+       }
        if (!rc)
                cxt->flags |= MNT_FL_TAB_APPLIED;
 
@@ -1293,7 +1318,7 @@ int test_mount(struct mtest *ts, int argc, char *argv[])
                return -ENOMEM;
 
        if (!strcmp(argv[idx], "-o")) {
-               mnt_context_set_optstr(cxt, argv[idx + 1]);
+               mnt_context_set_options(cxt, argv[idx + 1]);
                idx += 2;
        }
        if (!strcmp(argv[idx], "-t")) {
index fb593c3fd5143b3fd3e9a39e1b313e2468f1310b..b5a339f5f1c438462f67fbd7e90e8a3b99372e93 100644 (file)
 static int fix_optstr(mnt_context *cxt)
 {
        int rc = 0, rem_se = 0;
-       char *next, **optstr;
+       char *next;
        char *name, *val;
        size_t namesz, valsz;
+       mnt_fs *fs;
 
        assert(cxt);
        assert(cxt->fs);
@@ -45,18 +46,16 @@ static int fix_optstr(mnt_context *cxt)
 
        DBG(CXT, mnt_debug_h(cxt, "mount: fixing optstr"));
 
-       /*
-        * we directly work with optstr pointer here
-        */
-       optstr = &cxt->fs->optstr;
-       if (!optstr)
+       fs = cxt->fs;
+
+       if (!mnt_fs_get_vfs_options(fs) && !mnt_fs_get_userspace_options(fs))
                return 0;
 
        /* The propagation flags should not be used together with any other flags */
        if (cxt->mountflags & MS_PROPAGATION)
                cxt->mountflags &= MS_PROPAGATION;
 
-       if (*optstr && !mnt_optstr_get_option(*optstr, "user", &val, &valsz)) {
+       if (!mnt_optstr_get_option(fs->user_optstr, "user", &val, &valsz)) {
                if (val) {
                        cxt->orig_user = strndup(val, valsz);
                        if (!cxt->orig_user) {
@@ -70,29 +69,27 @@ static int fix_optstr(mnt_context *cxt)
        /*
         * Sync mount options with mount flags
         */
-       rc = mnt_optstr_apply_flags(optstr, cxt->mountflags,
+       rc = mnt_optstr_apply_flags(&fs->vfs_optstr, cxt->mountflags,
                                mnt_get_builtin_optmap(MNT_LINUX_MAP));
        if (rc)
                goto done;
 
-       rc = mnt_optstr_apply_flags(optstr, cxt->user_mountflags,
+       rc = mnt_optstr_apply_flags(&fs->user_optstr, cxt->user_mountflags,
                                mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
        if (rc)
                goto done;
 
-       next = *optstr;
+       next = fs->fs_optstr;
 
 #ifdef HAVE_LIBSELINUX
        rem_se = (cxt->mountflags & MS_REMOUNT) || !is_selinux_enabled();
 #endif
-       DBG(CXT, mnt_debug_h(cxt, "fixing mount options: '%s'", *optstr));
-
        while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) {
 
                if (namesz == 3 && !strncmp(name, "uid", 3))
-                       rc = mnt_optstr_fix_uid(optstr, val, valsz, &next);
+                       rc = mnt_optstr_fix_uid(&fs->fs_optstr, val, valsz, &next);
                else if (namesz == 3 && !strncmp(name, "gid", 3))
-                       rc = mnt_optstr_fix_gid(optstr, val, valsz, &next);
+                       rc = mnt_optstr_fix_gid(&fs->fs_optstr, val, valsz, &next);
 #ifdef HAVE_LIBSELINUX
                else if (namesz >= 7 && (!strncmp(name, "context", 7) ||
                                         !strncmp(name, "fscontext", 9) ||
@@ -101,51 +98,44 @@ static int fix_optstr(mnt_context *cxt)
                        if (rem_se) {
                                /* remove context= option */
                                next = name;
-                               rc = mnt_optstr_remove_option_at(optstr,
+                               rc = mnt_optstr_remove_option_at(&fs->fs_optstr,
                                                        name, val + valsz);
                        } else
-                               rc = mnt_optstr_fix_secontext(optstr,
+                               rc = mnt_optstr_fix_secontext(&fs->fs_optstr,
                                                        val, valsz, &next);
                }
 #endif
-               else if (namesz == 4 && (cxt->user_mountflags && MNT_MS_USER) &&
-                        !strncmp(name, "user", 4)) {
-
-                       rc = mnt_optstr_fix_user(optstr,
-                                                val ? val : name + namesz,
-                                                valsz, &next);
-               }
                if (rc)
                        goto done;
        }
 
+       if (!rc && cxt->user_mountflags && MNT_MS_USER)
+               rc = mnt_optstr_fix_user(&fs->fs_optstr);
+
 done:
-       __mnt_fs_set_optstr_ptr(cxt->fs, *optstr, TRUE);
-       DBG(CXT, mnt_debug_h(cxt, "fixed options [rc=%d]: '%s'", rc, *optstr));
+       DBG(CXT, mnt_debug_h(cxt, "fixed options [rc=%d]: "
+               "vfs='%s' fs='%s' user='%s'", rc,
+               fs->vfs_optstr, fs->fs_optstr, fs->user_optstr));
        return rc;
 }
 
 /*
  * Converts already evalulated and fixed options to the form that is compatible
  * with /sbin/mount.<type> helpers.
- *
- * Retursn newly allocated string.
  */
 static int generate_helper_optstr(mnt_context *cxt, char **optstr)
 {
-       const char *o;
        int rc = 0;
 
        assert(cxt);
        assert(cxt->fs);
        assert(optstr);
 
-       *optstr = NULL;
-       o = mnt_fs_get_optstr(cxt->fs);
+       *optstr = mnt_fs_strdup_options(cxt->fs);
+       if (!*optstr)
+               return -ENOMEM;
 
-       if (o)
-               rc = mnt_optstr_append_option(optstr, o, NULL);
-       if (!rc && (cxt->flags & MNT_FL_SAVED_USER))
+       if (cxt->flags & MNT_FL_SAVED_USER)
                rc = mnt_optstr_set_option(optstr, "user", cxt->orig_user);
        if (rc) {
                free(*optstr);
@@ -323,7 +313,6 @@ static int do_mount(mnt_context *cxt, const char *try_type)
        assert(cxt->fs);
        assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
 
-
        if (try_type && !cxt->helper) {
                rc = mnt_context_prepare_helper(cxt, "mount", try_type);
                if (!rc)
@@ -477,7 +466,7 @@ int mnt_context_do_mount(mnt_context *cxt)
        DBG(CXT, mnt_debug_h(cxt, "mount: do mount"));
 
        if (!(cxt->flags & MNT_FL_MOUNTDATA))
-               cxt->mountdata = (char *) mnt_fs_get_fs_optstr(cxt->fs);
+               cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs);
 
        type = mnt_fs_get_fstype(cxt->fs);
        if (type)
index ec571300414d873cb9333b2d700e81a7e0810572..b4da7373a6b2aeb7552f8fae0db8509b8e563bfa 100644 (file)
@@ -81,8 +81,14 @@ static int lookup_umount_fs(mnt_context *cxt)
 
        if (!rc && !mnt_fs_get_fstype(cxt->fs))
                rc = mnt_fs_set_fstype(cxt->fs, mnt_fs_get_fstype(fs));
+
+       if (!rc)
+               rc = mnt_fs_set_vfs_options(cxt->fs, mnt_fs_get_vfs_options(fs));
        if (!rc)
-               rc = mnt_fs_set_optstr(cxt->fs, mnt_fs_get_optstr(fs));
+               rc = mnt_fs_set_fs_options(cxt->fs, mnt_fs_get_fs_options(fs));
+       if (!rc)
+               rc = mnt_fs_set_userspace_options(cxt->fs, mnt_fs_get_userspace_options(fs));
+
        if (!rc && mnt_fs_get_bindsrc(fs))
                rc = mnt_fs_set_bindsrc(cxt->fs, mnt_fs_get_bindsrc(fs));
 
@@ -112,7 +118,7 @@ static int mnt_loopdev_associated_fs(const char *devname, mnt_fs *fs)
                return 0;
 
        /* check for offset option in @fs */
-       optstr = (char *) mnt_fs_get_optstr(fs);
+       optstr = (char *) mnt_fs_get_userspace_options(fs);
        if (optstr && !mnt_optstr_get_option(optstr, "offset=", &val, &valsz)) {
                int rc;
 
@@ -166,7 +172,7 @@ static int evaluate_permissions(mnt_context *cxt)
             (cxt->user_mountflags & MNT_MS_UHELPER)) {
 
                char *suffix = NULL;
-               char *o = (char *) mnt_fs_get_optstr(cxt->fs);
+               char *o = (char *) mnt_fs_get_userspace_options(cxt->fs);
                size_t valsz;
 
                rc = mnt_optstr_get_option(o, "uhelper", &suffix, &valsz);
@@ -236,11 +242,12 @@ static int evaluate_permissions(mnt_context *cxt)
         * The options `user', `owner' and `group' only allow unmounting by the
         * user that mounted (visible in mtab).
         */
-       optstr = mnt_fs_get_optstr(fs);         /* FSTAB mount options! */
+       optstr = mnt_fs_get_userspace_options(fs);      /* FSTAB mount options! */
        if (!optstr)
                goto eperm;
 
-       if (mnt_optstr_get_userspace_mountflags(optstr, &u_flags))
+       if (mnt_optstr_get_flags(optstr, &u_flags,
+                               mnt_get_builtin_optmap(MNT_USERSPACE_MAP)))
                goto eperm;
 
        if (u_flags & MNT_MS_USERS) {
@@ -271,7 +278,7 @@ static int evaluate_permissions(mnt_context *cxt)
                }
 
                /* get options from mtab */
-               optstr = mnt_fs_get_optstr(cxt->fs);
+               optstr = mnt_fs_get_userspace_options(cxt->fs);
                if (optstr && !mnt_optstr_get_option((char *) optstr,
                                        "user", &mtab_user, &sz) && sz)
                        ok = !strncmp(curr_user, mtab_user, sz);
@@ -491,7 +498,7 @@ int mnt_context_do_umount(mnt_context *cxt)
                /*
                 * update options to handle remount to read-only
                 */
-               const char *o = mnt_fs_get_optstr(cxt->fs);
+               const char *o = mnt_fs_get_vfs_options(cxt->fs);
                char *n = o ? strdup(o) : NULL;
 
                DBG(CXT, mnt_debug_h(cxt, "fix remount-on-umount update"));
@@ -500,7 +507,7 @@ int mnt_context_do_umount(mnt_context *cxt)
                        mnt_optstr_remove_option(&n, "rw");
                rc = mnt_optstr_prepend_option(&n, "ro", NULL);
                if (!rc)
-                       rc = __mnt_fs_set_optstr_ptr(cxt->fs, n, FALSE);
+                       rc = mnt_fs_set_vfs_options(cxt->fs, n);
 
                /* refresh options in /etc/mtab as well */
                if (!rc && cxt->update && cxt->mtab_writable)
index bcc53762828c95aa66f77a723438ebcf6086558b..b8e9085d1de4ebaa1c70119ab88e00e446dda785 100644 (file)
@@ -56,9 +56,10 @@ void mnt_free_fs(mnt_fs *fs)
        free(fs->root);
        free(fs->target);
        free(fs->fstype);
-       free(fs->optstr);
        free(fs->vfs_optstr);
        free(fs->fs_optstr);
+       free(fs->user_optstr);
+       free(fs->attrs);
 
        free(fs);
 }
@@ -125,12 +126,15 @@ mnt_fs *mnt_copy_fs(const mnt_fs *fs)
                goto err;
        if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, fstype)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, optstr)))
-               goto err;
        if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, vfs_optstr)))
                goto err;
        if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, fs_optstr)))
                goto err;
+       if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, user_optstr)))
+               goto err;
+       if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, attrs)))
+               goto err;
+
        n->freq       = fs->freq;
        n->passno     = fs->passno;
        n->flags      = fs->flags;
@@ -403,178 +407,499 @@ int mnt_fs_set_fstype(mnt_fs *fs, const char *fstype)
        return rc;
 }
 
+/*
+ * 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"
+ */
+static char *merge_optstr(const char *vfs, const char *fs)
+{
+       char *res, *p;
+       size_t sz;
+       int ro = 0, rw = 0;
+
+       if (!vfs && !fs)
+               return NULL;
+       if (!vfs || !fs)
+               return strdup(fs ? fs : vfs);
+       if (!strcmp(vfs, fs))
+               return strdup(vfs);             /* e.g. "aaa" and "aaa" */
+
+       /* leave space for leading "r[ow],", "," and trailing zero */
+       sz = strlen(vfs) + strlen(fs) + 5;
+       res = malloc(sz);
+       if (!res)
+               return NULL;
+       p = res + 3;                    /* make a room for rw/ro flag */
+
+       snprintf(p, sz - 3, "%s,%s", vfs, fs);
+
+       /* remove 'rw' flags */
+       rw += !mnt_optstr_remove_option(&p, "rw");      /* from vfs */
+       rw += !mnt_optstr_remove_option(&p, "rw");      /* from fs */
+
+       /* remove 'ro' flags if necessary */
+       if (rw != 2) {
+               ro += !mnt_optstr_remove_option(&p, "ro");
+               if (ro + rw < 2)
+                       ro += !mnt_optstr_remove_option(&p, "ro");
+       }
+
+       if (!strlen(p))
+               memcpy(res, ro ? "ro" : "rw", 3);
+       else
+               memcpy(res, ro ? "ro," : "rw,", 3);
+       return res;
+}
+
 /**
- * mnt_fs_get_optstr:
+ * mnt_fs_strdup_options:
  * @fs: fstab/mtab/mountinfo entry pointer
  *
- * Returns: pointer to mount option string with all options (FS and VFS)
+ * Merges all mount options (VFS, FS and userspace) to the one options string
+ * and returns the result. This function does not modigy @fs.
+ *
+ * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
  */
-const char *mnt_fs_get_optstr(mnt_fs *fs)
+char *mnt_fs_strdup_options(mnt_fs *fs)
 {
+       char *res;
+
        assert(fs);
-       return fs ? fs->optstr : NULL;
+
+       errno = 0;
+       res = merge_optstr(fs->vfs_optstr, fs->fs_optstr);
+       if (errno)
+               return NULL;
+       if (fs->user_optstr) {
+               if (mnt_optstr_append_option(&res, fs->user_optstr, NULL)) {
+                       free(res);
+                       res = NULL;
+               }
+       }
+       return res;
 }
 
-int __mnt_fs_set_optstr_ptr(mnt_fs *fs, char *ptr, int split)
+/**
+ * mnt_fs_set_options:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Splits @optstr to VFS, FS and userspace mount options and update relevat
+ * parts of @fs.
+ *
+ * Returns: 0 on success, or negative number icase of error.
+ */
+int mnt_fs_set_options(mnt_fs *fs, const char *optstr)
 {
-       char *v = NULL, *f = NULL;
+       char *v = NULL, *f = NULL, *u = NULL;
 
        assert(fs);
 
        if (!fs)
                return -EINVAL;
-       if (ptr) {
-               int rc = 0;
-
-               if (split)
-                       rc = mnt_split_optstr((char *) ptr, NULL, &v, &f, 0, 0);
+       if (optstr) {
+               int rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
                if (rc)
                        return rc;
        }
 
-       if (ptr != fs->optstr)
-               free(fs->optstr);
-
        free(fs->fs_optstr);
        free(fs->vfs_optstr);
+       free(fs->user_optstr);
 
-       fs->optstr = ptr;
        fs->fs_optstr = f;
        fs->vfs_optstr = v;
+       fs->user_optstr = u;
        return 0;
 }
 
-int __mnt_fs_set_optstr(mnt_fs *fs, const char *optstr, int split)
+/**
+ * mnt_fs_append_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: mount options
+ *
+ * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
+ * of options.
+ *
+ * If @optstr is NULL then @fs is not modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_options(mnt_fs *fs, const char *optstr)
 {
-       char *p;
+       char *v = NULL, *f = NULL, *u = NULL;
        int rc;
 
        assert(fs);
 
-       p = strdup(optstr);
-       if (!p)
-               return -ENOMEM;
-       rc = __mnt_fs_set_optstr_ptr(fs, p, split);
-       if (rc)
-               free(p);                /* error, deallocate */
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
+
+       rc = mnt_split_optstr((char *) optstr, &u, &v, &f, 0, 0);
+       if (!rc && v)
+               rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL);
+       if (!rc && f)
+              rc = mnt_optstr_append_option(&fs->fs_optstr, f, NULL);
+       if (!rc && u)
+              rc = mnt_optstr_append_option(&fs->user_optstr, u, NULL);
+
        return rc;
 }
 
 /**
- * mnt_fs_set_optstr:
+ * mnt_fs_prepend_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: mount options
+ *
+ * Parses (splits) @optstr and prepands results to VFS, FS and userspace lists
+ * of options.
+ *
+ * If @optstr is NULL then @fs is not modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_options(mnt_fs *fs, const char *optstr)
+{
+       char *v = NULL, *f = NULL, *u = NULL;
+       int rc;
+
+       assert(fs);
+
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
+
+       rc = mnt_split_optstr((char *) optstr, &u, &v, &f, 0, 0);
+       if (!rc && v)
+               rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL);
+       if (!rc && f)
+               rc = mnt_optstr_prepend_option(&fs->fs_optstr, f, NULL);
+       if (!rc && u)
+               rc = mnt_optstr_prepend_option(&fs->user_optstr, u, NULL);
+
+       return rc;
+}
+
+/*
+ * mnt_fs_get_fs_options:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns: pointer to superblock (fs-depend) mount option string or NULL.
+ */
+const char *mnt_fs_get_fs_options(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->fs_optstr : NULL;
+}
+
+/**
+ * mnt_fs_set_fs_options:
  * @fs: fstab/mtab/mountinfo entry
  * @optstr: options string
  *
- * This function creates a private copy of @optstr. The function also updates
- * VFS and FS mount options.
+ * Sets FS specific mount options.
  *
  * Returns: 0 on success or negative number in case of error.
  */
-int mnt_fs_set_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_set_fs_options(mnt_fs *fs, const char *optstr)
 {
-       return __mnt_fs_set_optstr(fs, optstr, TRUE);
+       char *p = NULL;
+
+       if (!fs)
+               return -EINVAL;
+       if (optstr) {
+               p = strdup(optstr);
+               if (!p)
+                       return -ENOMEM;
+       }
+       free(fs->fs_optstr);
+       fs->fs_optstr = p;
+
+       return 0;
 }
 
 /**
- * mnt_fs_append_userspace_optstr:
+ * mnt_fs_append_fs_options:
  * @fs: fstab/mtab/mountinfo entry
  * @optstr: options string
  *
- * This function appends @optstr to the current list of the mount options. The VFS and
- * FS mount options are not modified.
+ * Appends FS specific mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
  *
  * Returns: 0 on success or negative number in case of error.
  */
-int mnt_fs_append_userspace_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_append_fs_options(mnt_fs *fs, const char *optstr)
 {
-       assert(fs);
-       if (!fs || !optstr)
+       if (!fs)
                return -EINVAL;
-       return mnt_optstr_append_option(&fs->optstr, optstr, NULL);
+       if (!optstr)
+               return 0;
+       return mnt_optstr_append_option(&fs->fs_optstr, optstr, NULL);
 }
 
 /**
- * mnt_fs_append_optstr:
+ * mnt_fs_prepend_fs_options:
  * @fs: fstab/mtab/mountinfo entry
- * @optstr: mount options
+ * @optstr: options string
+ *
+ * Prepends FS specific mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
  *
  * Returns: 0 on success or negative number in case of error.
  */
-int mnt_fs_append_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_prepend_fs_options(mnt_fs *fs, const char *optstr)
 {
-       char *v = NULL, *f = NULL;
-       int rc;
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
+       return mnt_optstr_prepend_option(&fs->fs_optstr, optstr, NULL);
+}
 
+
+/**
+ * mnt_fs_get_vfs_options:
+ * @fs: fstab/mtab entry pointer
+ *
+ * Returns: pointer to fs-independent (VFS) mount option string or NULL.
+ */
+const char *mnt_fs_get_vfs_options(mnt_fs *fs)
+{
        assert(fs);
+       return fs ? fs->vfs_optstr : NULL;
+}
+
+/**
+ * mnt_fs_set_vfs_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Sets VFS mount options.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_set_vfs_options(mnt_fs *fs, const char *optstr)
+{
+       char *p = NULL;
+
+       if (!fs)
+               return -EINVAL;
+       if (optstr) {
+               p = strdup(optstr);
+               if (!p)
+                       return -ENOMEM;
+       }
+       free(fs->vfs_optstr);
+       fs->vfs_optstr = p;
+
+       return 0;
+}
 
+/**
+ * mnt_fs_append_vfs_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Appends VFS mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_vfs_options(mnt_fs *fs, const char *optstr)
+{
        if (!fs)
                return -EINVAL;
        if (!optstr)
                return 0;
+       return mnt_optstr_append_option(&fs->vfs_optstr, optstr, NULL);
+}
 
-       rc = mnt_split_optstr((char *) optstr, NULL, &v, &f, 0, 0);
-       if (!rc)
-               rc = mnt_optstr_append_option(&fs->optstr, optstr, NULL);
-       if (!rc && v)
-               rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL);
-       if (!rc && f)
-              rc = mnt_optstr_append_option(&fs->fs_optstr, f, NULL);
+/**
+ * mnt_fs_prepend_vfs_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Prepends VFS mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_vfs_options(mnt_fs *fs, const char *optstr)
+{
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
+       return mnt_optstr_prepend_option(&fs->vfs_optstr, optstr, NULL);
+}
 
-       return rc;
+/**
+ * mnt_fs_get_userspace_options:
+ * @fs: fstab/mtab entry pointer
+ *
+ * Returns: pointer to userspace mount option string or NULL.
+ */
+const char *mnt_fs_get_userspace_options(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->user_optstr : NULL;
 }
 
 /**
- * mnt_fs_prepend_optstr:
+ * mnt_fs_set_userspace_options:
  * @fs: fstab/mtab/mountinfo entry
- * @optstr: mount options
+ * @optstr: options string
+ *
+ * Sets userspace mount options.
  *
  * Returns: 0 on success or negative number in case of error.
  */
-int mnt_fs_prepend_optstr(mnt_fs *fs, const char *optstr)
+int mnt_fs_set_userspace_options(mnt_fs *fs, const char *optstr)
 {
-       char *v = NULL, *f = NULL;
-       int rc;
+       char *p = NULL;
 
-       assert(fs);
+       if (!fs)
+               return -EINVAL;
+       if (optstr) {
+               p = strdup(optstr);
+               if (!p)
+                       return -ENOMEM;
+       }
+       free(fs->user_optstr);
+       fs->user_optstr = p;
+
+       return 0;
+}
 
+/**
+ * mnt_fs_append_userspace_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Appends userspace mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_userspace_options(mnt_fs *fs, const char *optstr)
+{
        if (!fs)
                return -EINVAL;
        if (!optstr)
                return 0;
+       return mnt_optstr_append_option(&fs->user_optstr, optstr, NULL);
+}
 
-       rc = mnt_split_optstr((char *) optstr, NULL, &v, &f, 0, 0);
-       if (!rc)
-               rc = mnt_optstr_prepend_option(&fs->optstr, optstr, NULL);
-       if (!rc && v)
-               rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL);
-       if (!rc && f)
-               rc = mnt_optstr_prepend_option(&fs->fs_optstr, f, NULL);
+/**
+ * mnt_fs_prepend_userspace_options:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Prepends userspace mount options. If @optstr is NULL then @fs is not
+ * modified and 0 is returned.
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_userspace_options(mnt_fs *fs, const char *optstr)
+{
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
 
-       return rc;
+       return mnt_optstr_prepend_option(&fs->user_optstr, optstr, NULL);
 }
 
 /**
- * mnt_fs_get_fs_optstr:
- * @fs: fstab/mtab/mountinfo entry pointer
+ * mnt_fs_get_attributes:
+ * @fs: fstab/mtab entry pointer
  *
- * Returns: pointer to superblock (fs-depend) mount option string or NULL.
+ * Returns: pointer to attributes string or NULL.
  */
-const char *mnt_fs_get_fs_optstr(mnt_fs *fs)
+const char *mnt_fs_get_attributes(mnt_fs *fs)
 {
        assert(fs);
-       return fs ? fs->fs_optstr : NULL;
+       return fs ? fs->attrs : NULL;
 }
 
 /**
- * mnt_fs_get_vfs_optstr:
- * @fs: fstab/mtab entry pointer
+ * mnt_fs_set_attributes:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
  *
- * Returns: pointer to fs-independent (VFS) mount option string or NULL.
+ * Sets mount attributes. The attributes are mount(2) and mount(8) independent
+ * options, these options are not send to kernel and are not interpreted by
+ * libmount. The attributes are stored in /dev/.mount/utab only.
+ *
+ * The atrtributes are managed by libmount in userspace only. It's possible
+ * that information stored in userspace will not be available for libmount
+ * after CLONE_FS unshare. Be carefull, and don't use attributes if possible.
+ *
+ * Returns: 0 on success or negative number in case of error.
  */
-const char *mnt_fs_get_vfs_optstr(mnt_fs *fs)
+int mnt_fs_set_attributes(mnt_fs *fs, const char *optstr)
 {
-       assert(fs);
-       return fs ? fs->vfs_optstr : NULL;
+       char *p = NULL;
+
+       if (!fs)
+               return -EINVAL;
+       if (optstr) {
+               p = strdup(optstr);
+               if (!p)
+                       return -ENOMEM;
+       }
+       free(fs->attrs);
+       fs->attrs = p;
+
+       return 0;
+}
+
+/**
+ * mnt_fs_append_attributes
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Appends mount attributes. (See mnt_fs_set_attributes()).
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_append_attributes(mnt_fs *fs, const char *optstr)
+{
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
+       return mnt_optstr_append_option(&fs->attrs, optstr, NULL);
+}
+
+/**
+ * mnt_fs_prepend_attributes
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Prepends mount attributes. (See mnt_fs_set_attributes()).
+ *
+ * Returns: 0 on success or negative number in case of error.
+ */
+int mnt_fs_prepend_attributes(mnt_fs *fs, const char *optstr)
+{
+       if (!fs)
+               return -EINVAL;
+       if (!optstr)
+               return 0;
+       return mnt_optstr_prepend_option(&fs->attrs, optstr, NULL);
 }
 
 
@@ -754,8 +1079,34 @@ dev_t mnt_fs_get_devno(mnt_fs *fs)
 int mnt_fs_get_option(mnt_fs *fs, const char *name,
                char **value, size_t *valsz)
 {
-       char *optstr = (char *) mnt_fs_get_optstr(fs);
-       return optstr ? mnt_optstr_get_option(optstr, name, value, valsz) : 1;
+       char rc = 1;
+
+       if (fs->fs_optstr)
+               rc = mnt_optstr_get_option(fs->fs_optstr, name, value, valsz);
+       if (rc == 1 && fs->vfs_optstr)
+               rc = mnt_optstr_get_option(fs->vfs_optstr, name, value, valsz);
+       if (rc == 1 && fs->user_optstr)
+               rc = mnt_optstr_get_option(fs->user_optstr, name, value, valsz);
+       return rc;
+}
+
+/**
+ * mnt_fs_get_attribute:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @name: option name
+ * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
+ * @valsz: returns size of options value or 0
+ *
+ * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
+ */
+int mnt_fs_get_attribute(mnt_fs *fs, const char *name,
+               char **value, size_t *valsz)
+{
+       char rc = 1;
+
+       if (fs->attrs)
+               rc = mnt_optstr_get_option(fs->attrs, name, value, valsz);
+       return rc;
 }
 
 /**
@@ -901,7 +1252,13 @@ int mnt_fs_match_fstype(mnt_fs *fs, const char *types)
  */
 int mnt_fs_match_options(mnt_fs *fs, const char *options)
 {
-       return mnt_match_options(fs->optstr, options);
+       char *o = mnt_fs_strdup_options(fs);
+       int rc = 0;
+
+       if (o)
+               rc = mnt_match_options(o, options);
+       free(o);
+       return rc;
 }
 
 /**
@@ -919,7 +1276,15 @@ int mnt_fs_print_debug(mnt_fs *fs, FILE *file)
        fprintf(file, "source: %s\n", mnt_fs_get_source(fs));
        fprintf(file, "target: %s\n", mnt_fs_get_target(fs));
        fprintf(file, "fstype: %s\n", mnt_fs_get_fstype(fs));
-       fprintf(file, "optstr: %s\n", mnt_fs_get_optstr(fs));
+
+       if (mnt_fs_get_vfs_options(fs))
+               fprintf(file, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs));
+       if (mnt_fs_get_fs_options(fs))
+               fprintf(file, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs));
+       if (mnt_fs_get_userspace_options(fs))
+               fprintf(file, "user-optstr: %s\n", mnt_fs_get_userspace_options(fs));
+       if (mnt_fs_get_attributes(fs))
+               fprintf(file, "attributes: %s\n", mnt_fs_get_attributes(fs));
 
        if (mnt_fs_get_root(fs))
                fprintf(file, "root:   %s\n", mnt_fs_get_root(fs));
@@ -988,8 +1353,14 @@ int mnt_fs_to_mntent(mnt_fs *fs, struct mntent **mnt)
                goto err;
        if ((rc = cpy_str(&m->mnt_type, mnt_fs_get_fstype(fs))))
                goto err;
-       if ((rc = cpy_str(&m->mnt_opts, mnt_fs_get_optstr(fs))))
+
+       errno = 0;
+       m->mnt_opts = mnt_fs_strdup_options(fs);
+       if (!m->mnt_opts && errno) {
+               rc = -errno;
                goto err;
+       }
+
        m->mnt_freq = mnt_fs_get_freq(fs);
        m->mnt_passno = mnt_fs_get_passno(fs);
 
index 081cfe59e619fd0789581fd13ce9653265a02afd..02acddd12828a50ecde412fd037e93f9d12c513e 100644 (file)
@@ -168,16 +168,9 @@ extern int mnt_split_optstr(const char *optstr,
 
 extern int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
                                const struct mnt_optmap *map);
-extern int mnt_optstr_get_mountflags(const char *optstr, unsigned long *flags);
-extern int mnt_optstr_get_userspace_mountflags(const char *optstr, unsigned long *flags);
 extern int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
                                 const struct mnt_optmap *map);
 
-extern int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next);
-extern int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next);
-extern int mnt_optstr_fix_secontext(char **optstr, char *value, size_t valsz, char **next);
-extern int mnt_optstr_fix_user(char **optstr, char *value, size_t valsz, char **next);
-
 /* iter.c */
 enum {
 
@@ -220,13 +213,38 @@ extern const char *mnt_fs_get_target(mnt_fs *ent);
 extern int mnt_fs_set_target(mnt_fs *ent, const char *target);
 extern const char *mnt_fs_get_fstype(mnt_fs *ent);
 extern int mnt_fs_set_fstype(mnt_fs *ent, const char *fstype);
-extern const char *mnt_fs_get_optstr(mnt_fs *ent);
-extern int mnt_fs_set_optstr(mnt_fs *ent, const char *optstr);
-extern int mnt_fs_append_optstr(mnt_fs *fs, const char *optstr);
-extern int mnt_fs_prepend_optstr(mnt_fs *fs, const char *optstr);
-extern int mnt_fs_append_userspace_optstr(mnt_fs *fs, const char *optstr);
-extern const char *mnt_fs_get_vfs_optstr(mnt_fs *ent);
-extern const char *mnt_fs_get_fs_optstr(mnt_fs *ent);
+
+extern char *mnt_fs_strdup_options(mnt_fs *fs);
+extern int mnt_fs_set_options(mnt_fs *fs, const char *optstr);
+
+extern int mnt_fs_get_option(mnt_fs *ent, const char *name,
+                               char **value, size_t *valsz);
+
+extern int mnt_fs_append_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_fs_options(mnt_fs *fs);
+extern int mnt_fs_set_fs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_append_fs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_fs_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_vfs_options(mnt_fs *fs);
+extern int mnt_fs_set_vfs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_append_vfs_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_vfs_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_userspace_options(mnt_fs *fs);
+extern int mnt_fs_set_userspace_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_append_userspace_options(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_userspace_options(mnt_fs *fs, const char *optstr);
+
+extern const char *mnt_fs_get_attributes(mnt_fs *fs);
+extern int mnt_fs_set_attributes(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_get_attribute(mnt_fs *fs, const char *name,
+                               char **value, size_t *valsz);
+extern int mnt_fs_append_attributes(mnt_fs *fs, const char *optstr);
+extern int mnt_fs_prepend_attributes(mnt_fs *fs, const char *optstr);
+
 extern int mnt_fs_get_freq(mnt_fs *ent);
 extern int mnt_fs_set_freq(mnt_fs *ent, int freq);
 extern int mnt_fs_get_passno(mnt_fs *ent);
@@ -238,8 +256,6 @@ extern int mnt_fs_set_bindsrc(mnt_fs *fs, const char *src);
 extern int mnt_fs_get_id(mnt_fs *fs);
 extern int mnt_fs_get_parent_id(mnt_fs *fs);
 extern dev_t mnt_fs_get_devno(mnt_fs *fs);
-extern int mnt_fs_get_option(mnt_fs *ent, const char *name,
-                               char **value, size_t *valsz);
 
 extern int mnt_fs_match_target(mnt_fs *fs, const char *target, mnt_cache *cache);
 extern int mnt_fs_match_source(mnt_fs *fs, const char *source, mnt_cache *cache);
@@ -326,10 +342,10 @@ extern int mnt_context_set_fs(mnt_context *cxt, mnt_fs *fs);
 extern int mnt_context_set_source(mnt_context *cxt, const char *source);
 extern int mnt_context_set_target(mnt_context *cxt, const char *target);
 extern int mnt_context_set_fstype(mnt_context *cxt, const char *fstype);
-extern int mnt_context_set_optstr(mnt_context *cxt, const char *optstr);
-extern int mnt_context_append_optstr(mnt_context *cxt, const char *optstr);
+extern int mnt_context_set_options(mnt_context *cxt, const char *optstr);
+extern int mnt_context_append_options(mnt_context *cxt, const char *optstr);
 extern int mnt_context_set_fstype_pattern(mnt_context *cxt, const char *pattern);
-extern int mnt_context_set_optstr_pattern(mnt_context *cxt, const char *pattern);
+extern int mnt_context_set_options_pattern(mnt_context *cxt, const char *pattern);
 extern int mnt_context_set_fstab(mnt_context *cxt, mnt_tab *tb);
 extern int mnt_context_get_fstab(mnt_context *cxt, mnt_tab **tb);
 extern int mnt_context_get_mtab(mnt_context *cxt, mnt_tab **tb);
@@ -350,7 +366,6 @@ extern int mnt_context_do_umount(mnt_context *cxt);
 /*
  * mount(8) userspace options masks (MNT_MAP_USERSPACE map)
  */
-#define MNT_MS_DFLTS   (1 << 1)
 #define MNT_MS_NOAUTO  (1 << 2)
 #define MNT_MS_USER    (1 << 3)
 #define MNT_MS_USERS   (1 << 4)
index 07259d27bb6882c3e4c847c8504d933e6b0fbb79..5d51cded15129e32b06ef5c6ab8f52e0e81faf64 100644 (file)
@@ -15,18 +15,23 @@ global:
        mnt_free_fs;
        mnt_free_iter;
        mnt_free_lock;
-       mnt_free_update;
+       mnt_free_mntent;
        mnt_free_optls;
        mnt_free_tab;
-       mnt_fs_append_optstr;
-       mnt_fs_append_userspace_optstr;
+       mnt_free_update;
+       mnt_fs_append_attributes;
+       mnt_fs_append_fs_options;
+       mnt_fs_append_options;
+       mnt_fs_append_userspace_options;
+       mnt_fs_append_vfs_options;
+       mnt_fs_get_attributes;
+       mnt_fs_get_attribute;
        mnt_fs_get_devno;
        mnt_fs_get_freq;
-       mnt_fs_get_fs_optstr;
+       mnt_fs_get_fs_options;
        mnt_fs_get_fstype;
        mnt_fs_get_id;
        mnt_fs_get_option;
-       mnt_fs_get_optstr;
        mnt_fs_get_parent_id;
        mnt_fs_get_passno;
        mnt_fs_get_root;
@@ -35,28 +40,40 @@ global:
        mnt_fs_get_tag;
        mnt_fs_get_target;
        mnt_fs_get_userdata;
-       mnt_fs_get_vfs_optstr;
+       mnt_fs_get_userspace_options;
+       mnt_fs_get_vfs_options;
+       mnt_fs_set_vfs_options;
        mnt_fs_match_fstype;
        mnt_fs_match_options;
        mnt_fs_match_source;
        mnt_fs_match_target;
-       mnt_fs_prepend_optstr;
+       mnt_fs_prepend_attributes;
+       mnt_fs_prepend_fs_options;
+       mnt_fs_prepend_options;
+       mnt_fs_prepend_userspace_options;
+       mnt_fs_prepend_vfs_options;
        mnt_fs_print_debug;
+       mnt_fs_set_attributes;
        mnt_fs_set_freq;
+       mnt_fs_set_fs_options;
        mnt_fs_set_fstype;
-       mnt_fs_set_optstr;
+       mnt_fs_set_options;
        mnt_fs_set_passno;
        mnt_fs_set_root;
        mnt_fs_set_source;
        mnt_fs_set_target;
        mnt_fs_set_userdata;
+       mnt_fs_set_userspace_options;
+       mnt_fs_strdup_options;
+       mnt_fs_to_mntent;
        mnt_fstype_is_netfs;
        mnt_fstype_is_pseudofs;
        mnt_get_builtin_optmap;
-       mnt_get_library_version;
-       mnt_get_writable_mtab_path;
        mnt_get_fstab_path;
+       mnt_get_fstype;
+       mnt_get_library_version;
        mnt_get_mtab_path;
+       mnt_get_writable_mtab_path;
        mnt_init_debug;
        mnt_iter_get_direction;
        mnt_lock_file;
@@ -69,30 +86,23 @@ global:
        mnt_new_fs;
        mnt_new_iter;
        mnt_new_lock;
-       mnt_new_update;
        mnt_new_optls;
        mnt_new_tab;
        mnt_new_tab_from_file;
+       mnt_new_update;
        mnt_optstr_append_option;
-       mnt_optstr_get_mountflags;
+       mnt_optstr_apply_flags;
+       mnt_optstr_get_flags;
        mnt_optstr_get_option;
-       mnt_optstr_get_userspace_mountflags;
        mnt_optstr_next_option;
        mnt_optstr_prepend_option;
        mnt_optstr_remove_option;
        mnt_optstr_set_option;
-       mnt_optstr_fix_gid;
-       mnt_optstr_fix_selinux;
-       mnt_optstr_fix_uid;
-       mnt_optstr_fix_user;
-       mnt_optstr_apply_flags;
-       mnt_optstr_get_flags;
        mnt_parse_version_string;
        mnt_reset_iter;
        mnt_resolve_path;
        mnt_resolve_spec;
        mnt_resolve_tag;
-       mnt_get_fstype;
        mnt_split_optstr;
        mnt_tab_add_fs;
        mnt_tab_find_next_fs;
@@ -119,8 +129,10 @@ global:
        mnt_unlock_file;
        mnt_unmangle;
        mnt_update_disable_lock;
-       mnt_update_get_lock;
        mnt_update_file;
+       mnt_update_get_filename;
+       mnt_update_get_format;
+       mnt_update_get_lock;
        mnt_update_prepare_update;
        mnt_update_set_action;
        mnt_update_set_filename;
@@ -128,10 +140,6 @@ global:
        mnt_update_set_fs;
        mnt_update_set_mountflags;
        mnt_update_set_old_target;
-       mnt_update_get_format;
-       mnt_update_get_filename;
-       mnt_fs_to_mntent;
-       mnt_free_mntent;
 local:
        *;
 };
index 7eebb2094e89c79c0eb51ce2a9bf5e570747ebad..3403ab70582a5a1b078c8d424aab0d4f4537d6c6 100644 (file)
@@ -172,9 +172,10 @@ struct _mnt_fs {
        char            *target;        /* mountinfo[5], fstab[2]: mountpoint */
        char            *fstype;        /* mountinfo[9], fstab[3]: filesystem type */
 
-       char            *optstr;        /* mountinfo[6,11], fstab[4]: option string */
        char            *vfs_optstr;    /* mountinfo[6]: fs-independent (VFS) options */
        char            *fs_optstr;     /* mountinfo[11]: fs-depend options */
+       char            *user_optstr;   /* userspace mount options */
+       char            *attrs;         /* mount attributes */
 
        int             freq;           /* fstab[5]:  dump frequency in days */
        int             passno;         /* fstab[6]: pass number on parallel fsck */
@@ -299,6 +300,10 @@ extern int mnt_optmap_require_value(const struct mnt_optmap *mapent);
 
 /* optstr.c */
 extern int mnt_optstr_remove_option_at(char **optstr, char *begin, char *end);
+extern int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next);
+extern int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next);
+extern int mnt_optstr_fix_secontext(char **optstr, char *value, size_t valsz, char **next);
+extern int mnt_optstr_fix_user(char **optstr);
 
 /* fs.c */
 extern int __mnt_fs_set_source_ptr(mnt_fs *fs, char *source);
index d96da986ce2df460820b685f410323eea2759f01..d5f641096a6619ce79df95069bcacec96dd56a3b 100644 (file)
@@ -144,7 +144,7 @@ static const struct mnt_optmap linux_flags_map[] =
  */
 static const struct mnt_optmap userspace_opts_map[] =
 {
-   { "defaults", MNT_MS_DFLTS, MNT_NOMTAB },               /* default options */
+   { "defaults", 0, 0 },               /* default options */
 
    { "auto",    MNT_MS_NOAUTO, MNT_INVERT | MNT_NOMTAB },  /* Can be mounted using -a */
    { "noauto",  MNT_MS_NOAUTO, MNT_NOMTAB },               /* Can  only be mounted explicitly */
index 475c4cf1ff9ac934a2564d6532cdca075c55be55..62c5701dd2ef4b07b154dbaf7fe3572526f17353 100644 (file)
@@ -125,6 +125,9 @@ static int mnt_optstr_locate_option(char *optstr, const char *name,
        size_t namesz, nsz;
        int rc;
 
+       if (!optstr)
+               return 1;
+
        assert(name);
        assert(optstr);
 
@@ -223,7 +226,7 @@ int mnt_optstr_append_option(char **optstr, const char *name, const char *value)
        size_t vsz, nsz;
 
        if (!name)
-               return -EINVAL;
+               return 0;
 
        nsz = strlen(name);
        vsz = value ? strlen(value) : 0;
@@ -480,6 +483,9 @@ int mnt_split_optstr(const char *optstr, char **user, char **vfs, char **fs,
                const struct mnt_optmap *m =
                         mnt_optmap_get_entry(maps, 2, name, namesz, &ent);
 
+               if (ent && !ent->id)
+                       continue;       /* ignore undefined options (comments) */
+
                if (m && m == maps[0] && vfs) {
                        if (ignore_vfs && (ent->mask & ignore_vfs))
                                continue;
@@ -544,6 +550,8 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
                const struct mnt_optmap *ent;
 
                if (mnt_optmap_get_entry(maps, 1, name, namesz, &ent)) {
+                       if (!ent->id)
+                               continue;
                        if (ent->mask & MNT_INVERT)
                                *flags &= ~ent->id;
                        else
@@ -554,54 +562,6 @@ int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
        return 0;
 }
 
-/**
- * mnt_optstr_get_mountflags:
- * @optstr: string with comma separated list of options
- * @flags: returns mount flags
- *
- * For more details about mountflags see mount(2) syscall. The flags are
- * generated according to MNT_LINUX_MAP.
- *
- * For example:
- *
- *     "bind,exec,foo,bar"   --returns->   MS_BIND
- *
- *     "bind,noexec,foo,bar" --returns->   MS_BIND|MS_NOEXEC
- *
- * Note that @flags are not zeroized by this function! This function set/unset
- * bites in the @flags only.
- *
- * Returns: 0 on success or negative number in case of error
- */
-int mnt_optstr_get_mountflags(const char *optstr, unsigned long *flags)
-{
-       return mnt_optstr_get_flags(optstr, flags,
-                                   mnt_get_builtin_optmap(MNT_LINUX_MAP));
-}
-
-/**
- * mnt_optstr_get_userspace_mountflags:
- * @optstr: string with comma separated list of options
- * @flags: returns mount flags
- *
- * The mountflags are IDs from all MNT_USERSPACE_MAP options
- * map. See "struct mnt_optmap". These flags are not used for mount(2) syscall.
- *
- * For example:
- *
- *     "bind,exec,loop"   --returns->   MNT_MS_LOOP
- *
- * Note that @flags are not zeroized by this function! This function set/unset
- * bites in the @flags only.
- *
- * Returns: 0 on success or negative number in case of error
- */
-int mnt_optstr_get_userspace_mountflags(const char *optstr, unsigned long *flags)
-{
-       return mnt_optstr_get_flags(optstr, flags,
-                                   mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
-}
-
 /**
  * mnt_optstr_apply_mountflags:
  * @optstr: string with comma separated list of options
@@ -672,6 +632,8 @@ int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
                                /*
                                 * remove unwanted option (rw/ro is already set)
                                 */
+                               if (!ent->id)
+                                       continue;
                                if (ent->id == MS_RDONLY ||
                                    (ent->mask & MNT_INVERT) ||
                                    !(fl & ent->id)) {
@@ -725,8 +687,7 @@ err:
        return rc;
 }
 
-/**
- * mnt_optstr_fix_selinux:
+/*
  * @optstr: string with comma separated list of options
  * @value: pointer to the begin of the context value
  * @valsz: size of the value
@@ -814,8 +775,7 @@ static int set_uint_value(char **optstr, unsigned int num,
        return insert_value(optstr, begin, buf, next);
 }
 
-/**
- * mnt_optstr_fix_uid:
+/*
  * @optstr: string with comma separated list of options
  * @value: pointer to the begin of the uid value
  * @valsz: size of the value
@@ -866,8 +826,7 @@ int mnt_optstr_fix_uid(char **optstr, char *value, size_t valsz, char **next)
        return rc;
 }
 
-/**
- * mnt_optstr_fix_gid:
+/*
  * @optstr: string with comma separated list of options
  * @value: pointer to the begin of the uid value
  * @valsz: size of the value
@@ -913,40 +872,35 @@ int mnt_optstr_fix_gid(char **optstr, char *value, size_t valsz, char **next)
        return rc;
 }
 
-/**
- * mnt_optstr_fix_user:
- * @optstr: string with comma separated list of options
- * @value: pointer to place where has to start the value
- * @valsz: size of the value or zero if value not define
- * @next: returns pointer to the next option (optional argument)
-
- * Add/replace username. This is usually used to convert "user" (without value)
- * to to "user=<username>" -- in this case the @value has to pointer behind the
- * "user" option name; in case you want to replace already defined <username>
- * then the @valsz must be greater than zero.
+/*
+ * Converts "user" to "user=<username>".
  *
  * Returns: 0 on success, negative number in case of error.
  */
-int mnt_optstr_fix_user(char **optstr, char *value, size_t valsz, char **next)
+int mnt_optstr_fix_user(char **optstr)
 {
        char *username;
+       struct mnt_optloc ol;
        int rc = 0;
 
-       if (!optstr || !value)
-               return -EINVAL;
-
        DBG(CXT, mnt_debug("fixing user"));
 
+       mnt_init_optloc(&ol);
+
+       rc = mnt_optstr_locate_option(*optstr, "user", &ol);
+       if (rc)
+               return rc == 1 ? 0 : rc;        /* 1: user= not found */
+
        username = mnt_get_username(getuid());
        if (!username)
                return -ENOMEM;
 
-       if (!valsz || strncmp(value, username, valsz)) {
-               if (valsz)
+       if (!ol.valsz || strncmp(ol.value, username, ol.valsz)) {
+               if (ol.valsz)
                        /* remove old value */
-                       mnt_optstr_remove_option_at(optstr, value, value + valsz);
+                       mnt_optstr_remove_option_at(optstr, ol.value, ol.end);
 
-               rc = insert_value(optstr, value, username, next);
+               rc = insert_value(optstr, ol.value, username, NULL);
        }
 
        free(username);
@@ -1030,13 +984,13 @@ int test_flags(struct mtest *ts, int argc, char *argv[])
 
        optstr = strdup(argv[1]);
 
-       rc = mnt_optstr_get_mountflags(optstr, &fl);
+       rc = mnt_optstr_get_flags(optstr, &fl, mnt_get_builtin_optmap(MNT_LINUX_MAP));
        if (rc)
                return rc;
        printf("mountflags:           0x%08lx\n", fl);
 
        fl = 0;
-       rc = mnt_optstr_get_userspace_mountflags(optstr, &fl);
+       rc = mnt_optstr_get_flags(optstr, &fl, mnt_get_builtin_optmap(MNT_USERSPACE_MAP));
        if (rc)
                return rc;
        printf("userspace-mountflags: 0x%08lx\n", fl);
@@ -1164,12 +1118,11 @@ int test_fix(struct mtest *ts, int argc, char *argv[])
                        rc = mnt_optstr_fix_gid(&optstr, val, valsz, &next);
                else if (!strncmp(name, "context", 7))
                        rc = mnt_optstr_fix_secontext(&optstr, val, valsz, &next);
-               else if (!strncmp(name, "user", 4))
-                       rc = mnt_optstr_fix_user(&optstr,
-                                       val ? val : name + namesz, valsz, &next);
                if (rc)
                        break;
        }
+       if (rc)
+               rc = mnt_optstr_fix_user(&optstr);
 
        printf("fixed:  %s\n", optstr);
 
index d7c27e65f04bbdcc032b38faa2b8e515f81b425b..a6c14ffff5d1818fae2952676a85676087803ef7 100644 (file)
@@ -81,7 +81,8 @@ static int mnt_parse_tab_line(mnt_fs *fs, char *s)
                if (!rc)
                        rc = __mnt_fs_set_fstype_ptr(fs, fstype);
                if (!rc)
-                       rc = __mnt_fs_set_optstr_ptr(fs, optstr, TRUE);
+                       rc = mnt_fs_set_options(fs, optstr);
+               free(optstr);
        } else {
                DBG(TAB, mnt_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
                rc = -EINVAL;
@@ -210,10 +211,16 @@ static int mnt_parse_utab_line(mnt_fs *fs, const char *s)
                        if (!fs->bindsrc)
                                goto enomem;
 
-               } else if (!fs->optstr && !strncmp(p, "OPTS=", 5)) {
-                       fs->optstr = unmangle(p + 5, &end);
-                       if (!fs->optstr)
+               } else if (!fs->user_optstr && !strncmp(p, "OPTS=", 5)) {
+                       fs->user_optstr = unmangle(p + 5, &end);
+                       if (!fs->user_optstr)
                                goto enomem;
+
+               } else if (!fs->attrs && !strncmp(p, "ATTRS=", 6)) {
+                       fs->attrs = unmangle(p + 6, &end);
+                       if (!fs->attrs)
+                               goto enomem;
+
                } else {
                        /* unknown variable */
                        while (*p && *p != ' ') p++;
@@ -246,63 +253,6 @@ static int guess_tab_format(char *line)
        return MNT_FMT_FSTAB;
 }
 
-
-/*
- * 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"
-
- * We need this function for /proc/self/mountinfo parsing.
- */
-static char *merge_optstr(const char *vfs, const char *fs)
-{
-       char *res, *p;
-       size_t sz;
-       int ro = 0, rw = 0;
-
-       if (!vfs && !fs)
-               return NULL;
-       if (!vfs || !fs)
-               return strdup(fs ? fs : vfs);
-       if (!strcmp(vfs, fs))
-               return strdup(vfs);             /* e.g. "aaa" and "aaa" */
-
-       /* leave space for leading "r[ow],", "," and trailing zero */
-       sz = strlen(vfs) + strlen(fs) + 5;
-       res = malloc(sz);
-       if (!res)
-               return NULL;
-       p = res + 3;                    /* make a room for rw/ro flag */
-
-       snprintf(p, sz - 3, "%s,%s", vfs, fs);
-
-       /* remove 'rw' flags */
-       rw += !mnt_optstr_remove_option(&p, "rw");      /* from vfs */
-       rw += !mnt_optstr_remove_option(&p, "rw");      /* from fs */
-
-       /* remove 'ro' flags if necessary */
-       if (rw != 2) {
-               ro += !mnt_optstr_remove_option(&p, "ro");
-               if (ro + rw < 2)
-                       ro += !mnt_optstr_remove_option(&p, "ro");
-       }
-
-       if (!strlen(p))
-               memcpy(res, ro ? "ro" : "rw", 3);
-       else
-               memcpy(res, ro ? "ro," : "rw,", 3);
-       return res;
-}
-
 /*
  * Read and parse the next line from {fs,m}tab or mountinfo
  */
@@ -359,15 +309,6 @@ static int mnt_tab_parse_next(mnt_tab *tb, FILE *f, mnt_fs *fs,
        }
 
 
-       /* merge fs_optstr and vfs_optstr into optstr (necessary for "mountinfo") */
-       if (!fs->optstr && (fs->vfs_optstr || fs->fs_optstr)) {
-               fs->optstr = merge_optstr(fs->vfs_optstr, fs->fs_optstr);
-               if (!fs->optstr) {
-                       DBG(TAB, mnt_debug_h(tb, "failed to merge optstr"));
-                       return -ENOMEM;
-               }
-       }
-
        /*DBG(TAB, mnt_fs_print_debug(fs, stderr));*/
 
        return 0;
@@ -665,7 +606,7 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
 {
        mnt_fs *fs;
        mnt_iter itr;
-       const char *optstr, *src, *target, *root;
+       const char *optstr, *src, *target, *root, *attrs;
 
        assert(tb);
        assert(uf);
@@ -676,10 +617,11 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
 
        src = mnt_fs_get_srcpath(uf);
        target = mnt_fs_get_target(uf);
-       optstr = mnt_fs_get_optstr(uf);
+       optstr = mnt_fs_get_userspace_options(uf);
+       attrs = mnt_fs_get_attributes(uf);
        root = mnt_fs_get_root(uf);
 
-       if (!src || !target || !optstr || !root)
+       if (!src || !target || !root || (!attrs && !optstr))
                return NULL;
 
        mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
@@ -696,7 +638,8 @@ static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
 
        if (fs) {
                DBG(TAB, mnt_debug_h(tb, "found fs -- appending userspace optstr"));
-               mnt_fs_append_userspace_optstr(fs, optstr);
+               mnt_fs_append_userspace_options(fs, optstr);
+               mnt_fs_append_attributes(fs, attrs);
                mnt_fs_set_bindsrc(fs, mnt_fs_get_bindsrc(uf));
 
                DBG(TAB, mnt_debug_h(tb, "found fs:"));
index e9f6609ea06ccad982de1b6d0f421a19b4d2241c..ad7c19d74c727d1b00ac17aec0026604f0570bb0 100644 (file)
@@ -204,8 +204,7 @@ mnt_fs *mnt_update_get_fs(mnt_update *upd)
 static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
 {
        int rc = 0;
-       const char *o = NULL;
-       char *u = NULL;
+       const char *o = NULL, *a = NULL;
 
        assert(fs);
        assert(ent);
@@ -217,20 +216,10 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
 
        DBG(UPDATE, mnt_debug("prepare utab entry"));
 
-       o = mnt_fs_get_optstr(fs);
-       if (o) {
-               rc = mnt_split_optstr(o, &u, NULL, NULL, MNT_NOMTAB, 0);
-               if (rc)
-                       return rc;      /* parse error or so... */
-       }
-       /* TODO
-       if (extra_opts) {
-               rc = mnt_optstr_append_option(&u, extra_opts, NULL);
-               if (rc)
-                       goto err;
-       }
-       */
-       if (!u)
+       o = mnt_fs_get_userspace_options(fs);
+       a = mnt_fs_get_attributes(fs);
+
+       if (!o && !a)
                return 1;       /* don't have mount options */
 
        /* allocate the entry */
@@ -240,10 +229,12 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
                goto err;
        }
 
-       rc = __mnt_fs_set_optstr_ptr(*ent, u, FALSE);
+       rc = mnt_fs_set_userspace_options(*ent, o);
+       if (rc)
+               goto err;
+       rc = mnt_fs_set_attributes(*ent, a);
        if (rc)
                goto err;
-       u = NULL;
 
        if (!(mountflags & MS_REMOUNT)) {
                rc = set_fs_root(*ent, fs, mountflags);
@@ -254,15 +245,15 @@ static int utab_new_entry(mnt_fs *fs, unsigned long mountflags, mnt_fs **ent)
        DBG(UPDATE, mnt_debug("utab entry OK"));
        return 0;
 err:
-       free(u);
        mnt_free_fs(*ent);
+       *ent = NULL;
        return rc;
 }
 
 static int set_fs_root(mnt_fs *result, mnt_fs *fs, unsigned long mountflags)
 {
        char *root = NULL, *mnt = NULL;
-       const char *fstype, *optstr;
+       const char *fstype;
        mnt_tab *tb = NULL;
        int rc = -ENOMEM;
 
@@ -271,7 +262,6 @@ static int set_fs_root(mnt_fs *result, mnt_fs *fs, unsigned long mountflags)
 
        DBG(UPDATE, mnt_debug("setting FS root"));
 
-       optstr = mnt_fs_get_optstr(fs);
        fstype = mnt_fs_get_fstype(fs);
 
        /*
@@ -334,7 +324,7 @@ static int set_fs_root(mnt_fs *result, mnt_fs *fs, unsigned long mountflags)
                char *vol = NULL, *p;
                size_t sz, volsz = 0;
 
-               if (mnt_optstr_get_option((char *) optstr, "subvol", &vol, &volsz))
+               if (mnt_fs_get_option(fs, "subvol", &vol, &volsz))
                        goto dflt;
 
                sz = volsz;
@@ -371,16 +361,21 @@ err:
 /* mtab and fstab update */
 static int fprintf_mtab_fs(FILE *f, mnt_fs *fs)
 {
+       char *o;
        char *m1, *m2, *m3, *m4;
        int rc;
 
        assert(fs);
        assert(f);
 
+       o = mnt_fs_strdup_options(fs);
+       if (!o)
+               return -ENOMEM;
+
        m1 = mangle(mnt_fs_get_source(fs));
        m2 = mangle(mnt_fs_get_target(fs));
        m3 = mangle(mnt_fs_get_fstype(fs));
-       m4 = mangle(mnt_fs_get_optstr(fs));
+       m4 = mangle(o);
 
        if (m1 && m2 && m3 && m4)
                rc = !fprintf(f, "%s %s %s %s %d %d\n",
@@ -390,6 +385,7 @@ static int fprintf_mtab_fs(FILE *f, mnt_fs *fs)
        else
                rc = -ENOMEM;
 
+       free(o);
        free(m1);
        free(m2);
        free(m3);
@@ -428,12 +424,16 @@ static int fprintf_utab_fs(FILE *f, mnt_fs *fs)
                fprintf(f, "BINDSRC=%s ", p);
                free(p);
        }
-       p = mangle(mnt_fs_get_optstr(fs));
+       p = mangle(mnt_fs_get_attributes(fs));
+       if (p) {
+               fprintf(f, "ATTRS=%s ", p);
+               free(p);
+       }
+       p = mangle(mnt_fs_get_userspace_options(fs));
        if (p) {
                fprintf(f, "OPTS=%s", p);
                free(p);
        }
-
        fputc('\n', f);
 
        return 0;
@@ -620,12 +620,15 @@ static int update_modify_options(mnt_update *upd, mnt_lock *lc)
 {
        mnt_tab *tb = NULL;
        int rc = 0, u_lc = -1;
+       mnt_fs *fs;
 
        assert(upd);
        assert(upd->fs);
 
        DBG(UPDATE, mnt_debug_h(upd, "%s: modify options", upd->filename));
 
+       fs = upd->fs;
+
        if (lc)
                mnt_lock_file(lc);
        else if (upd->userspace_only)
@@ -635,20 +638,28 @@ static int update_modify_options(mnt_update *upd, mnt_lock *lc)
                        upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
        if (tb) {
                mnt_fs *cur = mnt_tab_find_target(tb,
-                                       mnt_fs_get_target(upd->fs),
+                                       mnt_fs_get_target(fs),
                                        MNT_ITER_BACKWARD);
                if (cur) {
-                       rc = mnt_fs_set_optstr(cur, mnt_fs_get_optstr(upd->fs));
+                       if (upd->userspace_only)
+                               rc = mnt_fs_set_attributes(cur, mnt_fs_get_attributes(fs));
+                       if (!rc && !upd->userspace_only)
+                               rc = mnt_fs_set_vfs_options(cur, mnt_fs_get_vfs_options(fs));
+                       if (!rc && !upd->userspace_only)
+                               rc = mnt_fs_set_fs_options(cur, mnt_fs_get_fs_options(fs));
+                       if (!rc)
+                               rc = mnt_fs_set_userspace_options(cur,
+                                               mnt_fs_get_userspace_options(fs));
                        if (!rc)
                                rc = update_tab(upd, tb);
                }
                mnt_free_tab(tb);
        }
+
        if (lc)
                mnt_unlock_file(lc);
        else if (u_lc != -1)
                utab_unlock(u_lc);
-
        return rc;
 }
 
@@ -747,7 +758,7 @@ static int test_add(struct mtest *ts, int argc, char *argv[])
        mnt_fs_set_source(fs, argv[1]);
        mnt_fs_set_target(fs, argv[2]);
        mnt_fs_set_fstype(fs, argv[3]);
-       mnt_fs_set_optstr(fs, argv[4]);
+       mnt_fs_set_options(fs, argv[4]);
 
        rc = update(NULL, fs, 0);
        mnt_free_fs(fs);
@@ -783,7 +794,7 @@ static int test_remount(struct mtest *ts, int argc, char *argv[])
        if (argc < 3)
                return -1;
        mnt_fs_set_target(fs, argv[1]);
-       mnt_fs_set_optstr(fs, argv[2]);
+       mnt_fs_set_options(fs, argv[2]);
 
        rc = update(NULL, fs, MS_REMOUNT);
        mnt_free_fs(fs);
index ff962cc82bc68f5be5eb101d4333e1ed43cb41a5..bc477826173c2702c52032a4ff98d2b7d02c5c5d 100644 (file)
@@ -3,7 +3,7 @@ ORIGINAL:
 source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0
 target: /
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   1
 COPY:
@@ -11,6 +11,6 @@ COPY:
 source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0
 target: /
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   1
index 4b1134cbb1981598f48b85c34e4c59723b773fcd..ce8f957d288e3e0932f8007e1e72bd7896a7123c 100644 (file)
@@ -2,4 +2,4 @@
 source: /dev/mapper/kzak-home
 target: /home/kzak
 fstype: ext4
-optstr: rw,noatime
+VFS-optstr: rw,noatime
index deebbf4cbe8c627076a7ac9e79cc943c46a8b46b..a49fdae25f4f703d976d2aeef4ec76c0c5560dd1 100644 (file)
@@ -2,6 +2,6 @@
 source: UUID=fef7ccb3-821c-4de8-88dc-71472be5946f
 target: /boot
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   2
index 8be992bcffda0da633fd9c1fce21d82018b7d60a..8d48723f8035458813d1b409d7865de4303cf515 100644 (file)
@@ -2,4 +2,4 @@
 source: /dev/mapper/foo
 target: /home/foo
 fstype: ext4
-optstr: noatime,defaults
+VFS-optstr: noatime
index 8d35862788557177d2e8c2f38333af8ab58f078e..3cdcc5d45326fcd4a21a5d199f181a957bc21822 100644 (file)
@@ -2,53 +2,49 @@
 source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0
 target: /
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   1
 ------ fs:
 source: UUID=fef7ccb3-821c-4de8-88dc-71472be5946f
 target: /boot
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   2
 ------ fs:
 source: UUID=1f2aa318-9c34-462e-8d29-260819ffd657
 target: swap
 fstype: swap
-optstr: defaults
 ------ fs:
 source: tmpfs
 target: /dev/shm
 fstype: tmpfs
-optstr: defaults
 ------ fs:
 source: devpts
 target: /dev/pts
 fstype: devpts
-optstr: gid=5,mode=620
+FS-opstr: gid=5,mode=620
 ------ fs:
 source: sysfs
 target: /sys
 fstype: sysfs
-optstr: defaults
 ------ fs:
 source: proc
 target: /proc
 fstype: proc
-optstr: defaults
 ------ fs:
 source: /dev/mapper/foo
 target: /home/foo
 fstype: ext4
-optstr: noatime,defaults
+VFS-optstr: noatime
 ------ fs:
 source: foo.com:/mnt/share
 target: /mnt/remote
 fstype: nfs
-optstr: noauto
+user-optstr: noauto
 ------ fs:
 source: //bar.com/gogogo
 target: /mnt/gogogo
 fstype: cifs
-optstr: user=SRGROUP/baby,noauto
+user-optstr: user=SRGROUP/baby,noauto
index f048e440d510e8c99dd0488cb44567d766473fb0..bf75661609d89247d0928251af913e09d66a8ba5 100644 (file)
@@ -4,54 +4,50 @@
 source: UUID=d3a8f783-df75-4dc8-9163-975a891052c0
 target: /
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   1
 ------ fs:
 source: UUID=fef7ccb3-821c-4de8-88dc-71472be5946f
 target: /boot
 fstype: ext3
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 pass:   2
 ------ fs:
 source: UUID=1f2aa318-9c34-462e-8d29-260819ffd657
 target: swap
 fstype: swap
-optstr: defaults
 ------ fs:
 source: tmpfs
 target: /dev/shm
 fstype: tmpfs
-optstr: defaults
 ------ fs:
 source: devpts
 target: /dev/pts
 fstype: devpts
-optstr: gid=5,mode=620
+FS-opstr: gid=5,mode=620
 ------ fs:
 source: sysfs
 target: /sys
 fstype: sysfs
-optstr: defaults
 ------ fs:
 source: proc
 target: /proc
 fstype: proc
-optstr: defaults
 ------ fs:
 source: /dev/mapper/foo
 target: /home/foo
 fstype: ext4
-optstr: noatime,defaults
+VFS-optstr: noatime
 freq:   1
 ------ fs:
 source: foo.com:/mnt/share
 target: /mnt/remote
 fstype: nfs
-optstr: noauto
+user-optstr: noauto
 ------ fs:
 source: //bar.com/gogogo
 target: /mnt/gogogo
 fstype: cifs
-optstr: user=SRGROUP/baby,noauto
+user-optstr: user=SRGROUP/baby,noauto
index a2de2ae7e27cfc16f25e88bdc8629f2fe74cb07d..aac3591e46b96cecdc0f7c683e624abb84e529dc 100644 (file)
@@ -2,7 +2,8 @@
 source: /proc
 target: /proc
 fstype: proc
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     15
 parent: 20
@@ -11,7 +12,8 @@ devno:  0:3
 source: /sys
 target: /sys
 fstype: sysfs
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     16
 parent: 20
@@ -20,7 +22,8 @@ devno:  0:15
 source: udev
 target: /dev
 fstype: devtmpfs
-optstr: rw,relatime,size=1983516k,nr_inodes=495879,mode=755
+VFS-optstr: rw,relatime
+FS-opstr: rw,size=1983516k,nr_inodes=495879,mode=755
 root:   /
 id:     17
 parent: 20
@@ -29,7 +32,8 @@ devno:  0:5
 source: devpts
 target: /dev/pts
 fstype: devpts
-optstr: rw,relatime,gid=5,mode=620,ptmxmode=000
+VFS-optstr: rw,relatime
+FS-opstr: rw,gid=5,mode=620,ptmxmode=000
 root:   /
 id:     18
 parent: 17
@@ -38,7 +42,8 @@ devno:  0:10
 source: tmpfs
 target: /dev/shm
 fstype: tmpfs
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     19
 parent: 17
@@ -47,7 +52,8 @@ devno:  0:16
 source: /dev/sda4
 target: /
 fstype: ext3
-optstr: rw,noatime,errors=continue,user_xattr,acl,barrier=0,data=ordered
+VFS-optstr: rw,noatime
+FS-opstr: rw,errors=continue,user_xattr,acl,barrier=0,data=ordered
 root:   /
 id:     20
 parent: 1
@@ -56,7 +62,8 @@ devno:  8:4
 source: tmpfs
 target: /sys/fs/cgroup
 fstype: tmpfs
-optstr: rw,nosuid,nodev,noexec,relatime,mode=755
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,mode=755
 root:   /
 id:     21
 parent: 16
@@ -65,7 +72,8 @@ devno:  0:17
 source: cgroup
 target: /sys/fs/cgroup/systemd
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd
 root:   /
 id:     22
 parent: 21
@@ -74,7 +82,8 @@ devno:  0:18
 source: cgroup
 target: /sys/fs/cgroup/cpuset
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,cpuset
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,cpuset
 root:   /
 id:     23
 parent: 21
@@ -83,7 +92,8 @@ devno:  0:19
 source: cgroup
 target: /sys/fs/cgroup/ns
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,ns
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,ns
 root:   /
 id:     24
 parent: 21
@@ -92,7 +102,8 @@ devno:  0:20
 source: cgroup
 target: /sys/fs/cgroup/cpu
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,cpu
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,cpu
 root:   /
 id:     25
 parent: 21
@@ -101,7 +112,8 @@ devno:  0:21
 source: cgroup
 target: /sys/fs/cgroup/cpuacct
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,cpuacct
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,cpuacct
 root:   /
 id:     26
 parent: 21
@@ -110,7 +122,8 @@ devno:  0:22
 source: cgroup
 target: /sys/fs/cgroup/memory
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,memory
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,memory
 root:   /
 id:     27
 parent: 21
@@ -119,7 +132,8 @@ devno:  0:23
 source: cgroup
 target: /sys/fs/cgroup/devices
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,devices
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,devices
 root:   /
 id:     28
 parent: 21
@@ -128,7 +142,8 @@ devno:  0:24
 source: cgroup
 target: /sys/fs/cgroup/freezer
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,freezer
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,freezer
 root:   /
 id:     29
 parent: 21
@@ -137,7 +152,8 @@ devno:  0:25
 source: cgroup
 target: /sys/fs/cgroup/net_cls
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,net_cls
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,net_cls
 root:   /
 id:     30
 parent: 21
@@ -146,7 +162,8 @@ devno:  0:26
 source: cgroup
 target: /sys/fs/cgroup/blkio
 fstype: cgroup
-optstr: rw,nosuid,nodev,noexec,relatime,blkio
+VFS-optstr: rw,nosuid,nodev,noexec,relatime
+FS-opstr: rw,blkio
 root:   /
 id:     31
 parent: 21
@@ -155,7 +172,8 @@ devno:  0:27
 source: systemd-1
 target: /sys/kernel/security
 fstype: autofs
-optstr: rw,relatime,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
+VFS-optstr: rw,relatime
+FS-opstr: rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
 root:   /
 id:     32
 parent: 16
@@ -164,7 +182,8 @@ devno:  0:28
 source: systemd-1
 target: /dev/hugepages
 fstype: autofs
-optstr: rw,relatime,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
+VFS-optstr: rw,relatime
+FS-opstr: rw,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
 root:   /
 id:     33
 parent: 17
@@ -173,7 +192,8 @@ devno:  0:29
 source: systemd-1
 target: /sys/kernel/debug
 fstype: autofs
-optstr: rw,relatime,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
+VFS-optstr: rw,relatime
+FS-opstr: rw,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
 root:   /
 id:     34
 parent: 16
@@ -182,7 +202,8 @@ devno:  0:30
 source: systemd-1
 target: /proc/sys/fs/binfmt_misc
 fstype: autofs
-optstr: rw,relatime,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
+VFS-optstr: rw,relatime
+FS-opstr: rw,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
 root:   /
 id:     35
 parent: 15
@@ -191,7 +212,8 @@ devno:  0:31
 source: systemd-1
 target: /dev/mqueue
 fstype: autofs
-optstr: rw,relatime,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
+VFS-optstr: rw,relatime
+FS-opstr: rw,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
 root:   /
 id:     36
 parent: 17
@@ -200,7 +222,8 @@ devno:  0:32
 source: /proc/bus/usb
 target: /proc/bus/usb
 fstype: usbfs
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     37
 parent: 15
@@ -209,7 +232,8 @@ devno:  0:14
 source: hugetlbfs
 target: /dev/hugepages
 fstype: hugetlbfs
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     38
 parent: 33
@@ -218,7 +242,8 @@ devno:  0:33
 source: mqueue
 target: /dev/mqueue
 fstype: mqueue
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     39
 parent: 36
@@ -227,7 +252,8 @@ devno:  0:12
 source: /dev/sda6
 target: /boot
 fstype: ext3
-optstr: rw,noatime,errors=continue,barrier=0,data=ordered
+VFS-optstr: rw,noatime
+FS-opstr: rw,errors=continue,barrier=0,data=ordered
 root:   /
 id:     40
 parent: 20
@@ -236,7 +262,8 @@ devno:  8:6
 source: /dev/mapper/kzak-home
 target: /home/kzak
 fstype: ext4
-optstr: rw,noatime,barrier=1,data=ordered
+VFS-optstr: rw,noatime
+FS-opstr: rw,barrier=1,data=ordered
 root:   /
 id:     41
 parent: 20
@@ -245,7 +272,8 @@ devno:  253:0
 source: (null)
 target: /proc/sys/fs/binfmt_misc
 fstype: binfmt_misc
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     42
 parent: 35
@@ -254,7 +282,8 @@ devno:  0:34
 source: fusectl
 target: /sys/fs/fuse/connections
 fstype: fusectl
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     43
 parent: 16
@@ -263,7 +292,8 @@ devno:  0:35
 source: gvfs-fuse-daemon
 target: /home/kzak/.gvfs
 fstype: fuse.gvfs-fuse-daemon
-optstr: rw,nosuid,nodev,relatime,user_id=500,group_id=500
+VFS-optstr: rw,nosuid,nodev,relatime
+FS-opstr: rw,user_id=500,group_id=500
 root:   /
 id:     44
 parent: 41
@@ -272,7 +302,8 @@ devno:  0:36
 source: sunrpc
 target: /var/lib/nfs/rpc_pipefs
 fstype: rpc_pipefs
-optstr: rw,relatime
+VFS-optstr: rw,relatime
+FS-opstr: rw
 root:   /
 id:     45
 parent: 20
@@ -281,7 +312,8 @@ devno:  0:37
 source: //foo.home/bar/
 target: /mnt/sounds
 fstype: cifs
-optstr: rw,relatime,unc=\\foo.home\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344
+VFS-optstr: rw,relatime
+FS-opstr: rw,unc=\\foo.home\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344
 root:   /
 id:     47
 parent: 20
index b8ea0cfd83cdb1614115bf0b0a24e987cb17c047..9838a9cd9e0f465ca5c7ed512ac5a4acaf8a2281 100644 (file)
@@ -2,54 +2,56 @@
 source: /dev/sda4
 target: /
 fstype: ext3
-optstr: rw,noatime
+VFS-optstr: rw,noatime
 ------ fs:
 source: proc
 target: /proc
 fstype: proc
-optstr: rw
+VFS-optstr: rw
 ------ fs:
 source: sysfs
 target: /sys
 fstype: sysfs
-optstr: rw
+VFS-optstr: rw
 ------ fs:
 source: devpts
 target: /dev/pts
 fstype: devpts
-optstr: rw,gid=5,mode=620
+VFS-optstr: rw
+FS-opstr: gid=5,mode=620
 ------ fs:
 source: tmpfs
 target: /dev/shm
 fstype: tmpfs
-optstr: rw
+VFS-optstr: rw
 ------ fs:
 source: /dev/sda6
 target: /boot
 fstype: ext3
-optstr: rw,noatime
+VFS-optstr: rw,noatime
 ------ fs:
 source: /dev/mapper/kzak-home
 target: /home/kzak
 fstype: ext4
-optstr: rw,noatime
+VFS-optstr: rw,noatime
 ------ fs:
 source: (null)
 target: /proc/sys/fs/binfmt_misc
 fstype: binfmt_misc
-optstr: rw
+VFS-optstr: rw
 ------ fs:
 source: fusectl
 target: /sys/fs/fuse/connections
 fstype: fusectl
-optstr: rw
+VFS-optstr: rw
 ------ fs:
 source: gvfs-fuse-daemon
 target: /home/kzak/.gvfs
 fstype: fuse.gvfs-fuse-daemon
-optstr: rw,nosuid,nodev,user=kzak
+VFS-optstr: rw,nosuid,nodev
+user-optstr: user=kzak
 ------ fs:
 source: sunrpc
 target: /var/lib/nfs/rpc_pipefs
 fstype: rpc_pipefs
-optstr: rw
+VFS-optstr: rw
index 6744e8c0e008a466b6bb52dbb6ada21cbf0921c8..271d86bc79cf6c354cd2c3192dd33a5f2c32b5d6 100644 (file)
@@ -1,4 +1,4 @@
-/dev/sda1 /mnt/foo ext3 rw,bbb,ccc,fff=FFF,ddd,noexec 0 0
-/dev/sdb1 /mnt/bar ext3 gg=G,ffff=f,ro,noatime 0 0
+/dev/sda1 /mnt/foo ext3 rw,noexec,bbb,ccc,fff=FFF,ddd 0 0
+/dev/sdb1 /mnt/bar ext3 ro,noatime,gg=G,ffff=f 0 0
 /dev/sda2 /mnt/bar ext3 rw,noatime 0 0
 /dev/sda1 /mnt/gogo ext3 rw,noatime,nosuid 0 0
index 6c6ec666147a9e0c2e5d8a06097a43af4318abc5..c6dffdbeb99bf8a0f3af78253b5f5979d56e9303 100644 (file)
@@ -1,4 +1,4 @@
-/dev/sda1 /mnt/newfoo ext3 rw,bbb,ccc,fff=FFF,ddd,noexec 0 0
-/dev/sdb1 /mnt/bar ext3 gg=G,ffff=f,ro,noatime 0 0
+/dev/sda1 /mnt/newfoo ext3 rw,noexec,bbb,ccc,fff=FFF,ddd 0 0
+/dev/sdb1 /mnt/bar ext3 ro,noatime,gg=G,ffff=f 0 0
 /dev/sda2 /mnt/newbar ext3 rw,noatime 0 0
 /dev/sda1 /mnt/gogo ext3 rw,noatime,nosuid 0 0