]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add and copy FS internal flags
authorKarel Zak <kzak@redhat.com>
Mon, 7 Feb 2011 14:17:07 +0000 (15:17 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 7 Feb 2011 14:17:07 +0000 (15:17 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/mount/src/context_umount.c
shlibs/mount/src/fs.c
shlibs/mount/src/libmount.h.in
shlibs/mount/src/libmount.sym
shlibs/mount/src/mountP.h
shlibs/mount/src/tab.c
shlibs/mount/src/tab_parse.c
shlibs/mount/src/tab_update.c

index 122ef7f840d76cb3db3598544e462c8a31786f16..bd9be695601d935e37fa1c997dd7037bc6aa72b9 100644 (file)
@@ -25,7 +25,7 @@ static int lookup_umount_fs(struct libmnt_context *cxt)
 {
        int rc;
        const char *tgt;
-       struct libmnt_table *mtab;
+       struct libmnt_table *mtab = NULL;
        struct libmnt_fs *fs;
 
        assert(cxt);
@@ -69,30 +69,19 @@ static int lookup_umount_fs(struct libmnt_context *cxt)
        }
 
        if (!fs) {
-               DBG(CXT, mnt_debug_h(cxt, "cannot found %s in mtab", tgt));
+               DBG(CXT, mnt_debug_h(cxt, "umount: cannot found %s in mtab", tgt));
                return 0;
        }
 
        /* copy from mtab to our FS description
         */
-       rc = mnt_fs_set_source(cxt->fs, mnt_fs_get_source(fs));
-       if (!rc)
-               rc = mnt_fs_set_target(cxt->fs, mnt_fs_get_target(fs));
-
-       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_fs_options(cxt->fs, mnt_fs_get_fs_options(fs));
-       if (!rc)
-               rc = mnt_fs_set_user_options(cxt->fs, mnt_fs_get_user_options(fs));
-       if (!rc)
-               rc = mnt_fs_set_attributes(cxt->fs, mnt_fs_get_attributes(fs));
+       mnt_fs_set_source(cxt->fs, NULL);
+       mnt_fs_set_target(cxt->fs, NULL);
 
-       if (!rc && mnt_fs_get_bindsrc(fs))
-               rc = mnt_fs_set_bindsrc(cxt->fs, mnt_fs_get_bindsrc(fs));
+       if (!mnt_copy_fs(cxt->fs, fs)) {
+               DBG(CXT, mnt_debug_h(cxt, "umount: failed to copy FS"));
+               return -errno;
+       }
 
        DBG(CXT, mnt_debug_h(cxt, "umount: mtab applied"));
        cxt->flags |= MNT_FL_TAB_APPLIED;
index 1477812f601fdda2e5f40c824ed6326d7334729d..c2deff5f1f992561c5935fb3b27aaff3e99c8446 100644 (file)
@@ -33,6 +33,7 @@ struct libmnt_fs *mnt_new_fs(void)
        if (!fs)
                return NULL;
 
+       /*DBG(FS, mnt_debug_h(fs, "alloc"));*/
        INIT_LIST_HEAD(&fs->ents);
        return fs;
 }
@@ -49,6 +50,8 @@ void mnt_free_fs(struct libmnt_fs *fs)
                return;
        list_del(&fs->ents);
 
+       /*DBG(FS, mnt_debug_h(fs, "free"));*/
+
        free(fs->source);
        free(fs->bindsrc);
        free(fs->tagname);
@@ -64,7 +67,19 @@ void mnt_free_fs(struct libmnt_fs *fs)
        free(fs);
 }
 
-static inline int cpy_str(char **dest, const char *src)
+/**
+ * mnt_reset_fs:
+ * @fs: fs pointer
+ *
+ * Resets (zeroize) @fs.
+ */
+void mnt_reset_fs(struct libmnt_fs *fs)
+{
+       if (fs)
+               memset(fs, 0, sizeof(*fs));
+}
+
+static inline int update_str(char **dest, const char *src)
 {
        size_t sz;
        char *x;
@@ -91,57 +106,71 @@ static inline int cpy_str_at_offset(void *new, const void *old, size_t offset)
        char **o = (char **) (old + offset);
        char **n = (char **) (new + offset);
 
-       return cpy_str(n, *o);
+       if (*n)
+               return 0;       /* already set, not overwrite */
+
+       return update_str(n, *o);
 }
 
 /**
  * mnt_copy_fs:
- * @fs: source FS
+ * @dest: destination FS
+ * @src: source FS
+ *
+ * If @dest is NULL, then a new FS is allocated, if any @dest field is already
+ * set then the field is NOT overwrited.
  *
  * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is
  * not linked with any existing mnt_tab.
  *
- * Returns: copy of @fs
+ * Returns: @dest or NULL in case of error
  */
-struct libmnt_fs *mnt_copy_fs(const struct libmnt_fs *fs)
+struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest,
+                             const struct libmnt_fs *src)
 {
-       struct libmnt_fs *n = mnt_new_fs();
+       const struct libmnt_fs *org = dest;
 
-       if (!n)
-               return NULL;
+       if (!dest) {
+               dest = mnt_new_fs();
+               if (!dest)
+                       return NULL;
+       }
 
-       n->id         = fs->id;
-       n->parent     = fs->parent;
-       n->devno      = fs->devno;
+       /*DBG(FS, mnt_debug_h(dest, "copy from %p", src));*/
 
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, source)))
+       dest->id         = src->id;
+       dest->parent     = src->parent;
+       dest->devno      = src->devno;
+
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, source)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, tagname)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, tagname)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, tagval)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, tagval)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, root)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, root)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, target)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, target)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, fstype)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fstype)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, vfs_optstr)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, vfs_optstr)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, fs_optstr)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fs_optstr)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, user_optstr)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, user_optstr)))
                goto err;
-       if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, attrs)))
+       if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, attrs)))
                goto err;
 
-       n->freq       = fs->freq;
-       n->passno     = fs->passno;
-       n->flags      = fs->flags;
+       dest->freq       = src->freq;
+       dest->passno     = src->passno;
+       dest->flags      = src->flags;
 
-       return n;
+       return dest;
 err:
-       mnt_free_fs(n);
+       if (!org)
+               mnt_free_fs(dest);
        return NULL;
 }
 
@@ -400,6 +429,31 @@ int mnt_fs_set_target(struct libmnt_fs *fs, const char *target)
        return 0;
 }
 
+int __mnt_fs_get_flags(struct libmnt_fs *fs)
+{
+       return fs ? fs->flags : 0;
+}
+
+int __mnt_fs_set_flags(struct libmnt_fs *fs, int flags)
+{
+       if (fs) {
+               fs->flags = flags;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+/**
+ * mnt_fs_is_kernel:
+ * @fs: filesystem
+ *
+ * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts.
+ */
+int mnt_fs_is_kernel(struct libmnt_fs *fs)
+{
+       return __mnt_fs_get_flags(fs) & MNT_FS_KERNEL;
+}
+
 /**
  * mnt_fs_get_fstype:
  * @fs: fstab/mtab/mountinfo entry pointer
@@ -1400,11 +1454,11 @@ int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt)
                        return -ENOMEM;
        }
 
-       if ((rc = cpy_str(&m->mnt_fsname, mnt_fs_get_source(fs))))
+       if ((rc = update_str(&m->mnt_fsname, mnt_fs_get_source(fs))))
                goto err;
-       if ((rc = cpy_str(&m->mnt_dir, mnt_fs_get_target(fs))))
+       if ((rc = update_str(&m->mnt_dir, mnt_fs_get_target(fs))))
                goto err;
-       if ((rc = cpy_str(&m->mnt_type, mnt_fs_get_fstype(fs))))
+       if ((rc = update_str(&m->mnt_type, mnt_fs_get_fstype(fs))))
                goto err;
 
        errno = 0;
index aa00b938dc5da20df15fef3833ea23b733b614ee..1831ed18a92c8dfe808e8a2ad1a5846913d58865 100644 (file)
@@ -199,7 +199,9 @@ extern int mnt_lock_file(struct libmnt_lock *ml);
 /* fs.c */
 extern struct libmnt_fs *mnt_new_fs(void);
 extern void mnt_free_fs(struct libmnt_fs *fs);
-extern struct libmnt_fs *mnt_copy_fs(const struct libmnt_fs *fs);
+extern void mnt_reset_fs(struct libmnt_fs *fs);
+extern struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest,
+                                    const struct libmnt_fs *src);
 extern void *mnt_fs_get_userdata(struct libmnt_fs *fs);
 extern int mnt_fs_set_userdata(struct libmnt_fs *fs, void *data);
 extern const char *mnt_fs_get_source(struct libmnt_fs *fs);
@@ -263,6 +265,8 @@ extern int mnt_fs_match_fstype(struct libmnt_fs *fs, const char *types);
 extern int mnt_fs_match_options(struct libmnt_fs *fs, const char *options);
 extern int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file);
 
+extern int mnt_fs_is_kernel(struct libmnt_fs *fs);
+
 extern void mnt_free_mntent(struct mntent *mnt);
 extern int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt);
 
index 2481b4931a8cab6b9eca0153b4245ddb87b9395b..d0ebfd728effa7e7abe95671b44358d3965cee59 100644 (file)
@@ -36,6 +36,7 @@ global:
        mnt_context_get_status;
        mnt_context_get_target;
        mnt_context_get_user_mflags;
+       mnt_context_helper_setopt;
        mnt_context_init_helper;
        mnt_context_is_fake;
        mnt_context_is_force;
@@ -46,7 +47,6 @@ global:
        mnt_context_is_sloppy;
        mnt_context_is_verbose;
        mnt_context_mount;
-       mnt_context_helper_setopt;
        mnt_context_prepare_mount;
        mnt_context_prepare_umount;
        mnt_context_set_cache;
@@ -98,6 +98,7 @@ global:
        mnt_fs_get_userdata;
        mnt_fs_get_user_options;
        mnt_fs_get_vfs_options;
+       mnt_fs_is_kernel;
        mnt_fs_match_fstype;
        mnt_fs_match_options;
        mnt_fs_match_source;
@@ -157,6 +158,7 @@ global:
        mnt_optstr_set_option;
        mnt_parse_version_string;
        mnt_reset_context;
+       mnt_reset_fs;
        mnt_reset_iter;
        mnt_resolve_path;
        mnt_resolve_spec;
index a38aa10e433793746902f262b6cbab04bde9dad7..aeceb7f964b2cf836cf2eb3e995a5ef4fa885fa2 100644 (file)
@@ -193,6 +193,12 @@ struct libmnt_fs {
 #define MNT_FS_PSEUDO  (1 << 1) /* pseudo filesystem */
 #define MNT_FS_NET     (1 << 2) /* network filesystem */
 #define MNT_FS_SWAP    (1 << 3) /* swap device */
+#define MNT_FS_KERNEL  (1 << 4) /* data from /proc/{mounts,self/mountinfo} */
+#define MNT_FS_MERGED  (1 << 5) /* already merged data from /dev/.mount/utab */
+
+extern int __mnt_fs_get_flags(struct libmnt_fs *fs);
+extern int __mnt_fs_set_flags(struct libmnt_fs *fs, int flags);
+
 
 /*
  * mtab/fstab/mountinfo file
index ab411768366e76baa22b2e511496b70084326e38..2d2e72fd1ec49e1b53e2b4a3c7d81258cbffaaf5 100644 (file)
@@ -424,7 +424,7 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat
        if (!tb || !path)
                return NULL;
 
-       DBG(TAB, mnt_debug_h(tb, "lookup target: %s", path));
+       DBG(TAB, mnt_debug_h(tb, "lookup TARGET: %s", path));
 
        /* native @target */
        mnt_reset_iter(&itr, direction);
@@ -733,7 +733,7 @@ int test_copy_fs(struct libmnt_test *ts, int argc, char *argv[])
        printf("ORIGINAL:\n");
        mnt_fs_print_debug(fs, stdout);
 
-       fs = mnt_copy_fs(fs);
+       fs = mnt_copy_fs(NULL, fs);
        if (!fs)
                goto done;
 
index 42b108ff8c7baf0ffcd9406ab0f1cc77da3384aa..4eb32eb63dc267b3242047c802194739d27d6308 100644 (file)
@@ -140,6 +140,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, char *s)
                        &fs->fs_optstr);
 
        if (rc == 10) {
+               fs->flags |= MNT_FS_KERNEL;
                fs->devno = makedev(maj, min);
 
                unmangle_string(fs->root);
@@ -335,6 +336,7 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam
 {
        int nlines = 0;
        int rc = -1;
+       int flags = 0;
 
        assert(tb);
        assert(f);
@@ -342,6 +344,12 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam
 
        DBG(TAB, mnt_debug_h(tb, "%s: start parsing", filename));
 
+       /* necessary for /proc/mounts only, the /proc/self/mountinfo
+        * parser sets propertly the flag
+        */
+       if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0)
+               flags = MNT_FS_KERNEL;
+
        while (!feof(f)) {
                struct libmnt_fs *fs = mnt_new_fs();
 
@@ -349,8 +357,10 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam
                        goto err;
 
                rc = mnt_table_parse_next(tb, f, fs, filename, &nlines);
-               if (!rc)
+               if (!rc) {
                        rc = mnt_table_add_fs(tb, fs);
+                       fs->flags |= flags;
+               }
                if (rc) {
                        mnt_free_fs(fs);
                        if (rc == 1)
@@ -631,6 +641,9 @@ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct
                           *t = mnt_fs_get_target(fs),
                           *r = mnt_fs_get_root(fs);
 
+               if (fs->flags & MNT_FS_MERGED)
+                       continue;
+
                if (s && t && r && !strcmp(t, target) &&
                    !strcmp(s, src) && !strcmp(r, root))
                        break;
@@ -641,6 +654,7 @@ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct
                mnt_fs_append_user_options(fs, optstr);
                mnt_fs_append_attributes(fs, attrs);
                mnt_fs_set_bindsrc(fs, mnt_fs_get_bindsrc(uf));
+               fs->flags |= MNT_FS_MERGED;
 
                DBG(TAB, mnt_debug_h(tb, "found fs:"));
                DBG(TAB, mnt_fs_print_debug(fs, stderr));
index 60a628a4a978354ab1915a325e6c4361419396e1..d66b64f940392adf9d754dd2a66aba301af38179 100644 (file)
@@ -324,7 +324,7 @@ static int utab_new_entry(struct libmnt_fs *fs, unsigned long mountflags, struct
        }
 
        /* allocate the entry */
-       *ent = mnt_copy_fs(fs);
+       *ent = mnt_copy_fs(NULL, fs);
        if (!*ent) {
                rc = -ENOMEM;
                goto err;