From 9d5eb4c46405413a8dd69d01f4e094f4390944d1 Mon Sep 17 00:00:00 2001 From: Tim Hildering Date: Mon, 4 Mar 2019 19:15:08 +0100 Subject: libmount: improve fs referencing in tables * Added member 'struct libmnt_table *tab' to libmnt_fs structure. * Added 'mnt_fs_get_table()'. * Removed overhead from 'mnt_table_{insert,move,remove}_fs(). * Added check to 'mnt_table_set_iter()' that entry is member of table. [kzak@redhat.com: - add to libmount.sys - add to docs - cleanup commit message - set fs->tab = NULL before mnt_unref_fs() in mnt_table_remove_fs()] Signed-off-by: Tim Hildering Signed-off-by: Karel Zak --- libmount/src/fs.c | 17 +++++++++++++++++ libmount/src/libmount.h.in | 1 + libmount/src/libmount.sym | 1 + libmount/src/mountP.h | 1 + libmount/src/tab.c | 20 +++++++++++--------- 5 files changed, 31 insertions(+), 9 deletions(-) (limited to 'libmount/src') diff --git a/libmount/src/fs.c b/libmount/src/fs.c index 9971d6ae3..147398955 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -190,6 +190,7 @@ struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, return NULL; } + dest->tab = NULL; dest->id = src->id; dest->parent = src->parent; dest->devno = src->devno; @@ -445,6 +446,22 @@ int mnt_fs_streq_srcpath(struct libmnt_fs *fs, const char *path) return p && path && strcmp(p, path) == 0; } +/** + * mnt_fs_get_table: + * @fs: table entry + * @tb: table that contains @fs + * + * Returns: 0 or negative number on error (if @fs or @tb is NULL). + */ +int mnt_fs_get_table(struct libmnt_fs *fs, struct libmnt_table **tb) +{ + if (!fs || !tb) + return -EINVAL; + + *tb = fs->tab; + return 0; +} + /** * mnt_fs_streq_target: * @fs: fs diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index fb86aaff9..19535bd7f 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -439,6 +439,7 @@ extern int mnt_fs_set_userdata(struct libmnt_fs *fs, void *data); extern const char *mnt_fs_get_source(struct libmnt_fs *fs); extern int mnt_fs_set_source(struct libmnt_fs *fs, const char *source); extern const char *mnt_fs_get_srcpath(struct libmnt_fs *fs); +extern int mnt_fs_get_table(struct libmnt_fs *fs, struct libmnt_table **tb); extern int mnt_fs_get_tag(struct libmnt_fs *fs, const char **name, const char **value); diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index 1d72cf4f7..b92728ff6 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -344,6 +344,7 @@ MOUNT_2.33 { MOUNT_2.34 { mnt_context_next_remount; + mnt_fs_get_table; mnt_guess_system_root; mnt_table_find_fs; mnt_table_insert_fs; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index 7887c0a55..11fc28315 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -170,6 +170,7 @@ struct libmnt_iter { */ struct libmnt_fs { struct list_head ents; + struct libmnt_table *tab; int refcount; /* reference counter */ int id; /* mountinfo[1]: ID */ diff --git a/libmount/src/tab.c b/libmount/src/tab.c index 674dc67e5..6d2fdc0d5 100644 --- a/libmount/src/tab.c +++ b/libmount/src/tab.c @@ -443,11 +443,12 @@ int mnt_table_add_fs(struct libmnt_table *tb, struct libmnt_fs *fs) if (!tb || !fs) return -EINVAL; - if (!list_empty(&fs->ents)) + if (fs->tab) return -EBUSY; mnt_ref_fs(fs); list_add_tail(&fs->ents, &tb->ents); + fs->tab = tb; tb->nents++; DBG(TAB, ul_debugobj(tb, "add entry: %s %s", @@ -466,6 +467,7 @@ static int __table_insert_fs( else list_add_tail(&fs->ents, head); + fs->tab = tb; tb->nents++; DBG(TAB, ul_debugobj(tb, "insert entry: %s %s", @@ -487,7 +489,6 @@ static int __table_insert_fs( * This function inncrements reference to @fs. Don't forget to use * mnt_unref_fs() after mnt_table_insert_fs() if you want to keep the @fs * referenced by the table only. - * * Returns: 0 on success or negative number in case of error. */ @@ -497,10 +498,10 @@ int mnt_table_insert_fs(struct libmnt_table *tb, int before, if (!tb || !fs) return -EINVAL; - if (!list_empty(&fs->ents)) + if (fs->tab) return -EBUSY; - if (pos && mnt_table_find_fs(tb, pos) < 1) + if (pos && pos->tab != tb) return -ENOENT; mnt_ref_fs(fs); @@ -529,10 +530,7 @@ int mnt_table_move_fs(struct libmnt_table *src, struct libmnt_table *dst, if (!src || !dst || !fs) return -EINVAL; - if (mnt_table_find_fs(src, fs) < 1) - return -ENOENT; - - if (pos && mnt_table_find_fs(dst, pos) < 1) + if (fs->tab != src || (pos && pos->tab != dst)) return -ENOENT; /* remove from source */ @@ -557,9 +555,10 @@ int mnt_table_move_fs(struct libmnt_table *src, struct libmnt_table *dst, */ int mnt_table_remove_fs(struct libmnt_table *tb, struct libmnt_fs *fs) { - if (!tb || !fs || mnt_table_find_fs(tb, fs) < 1) + if (!tb || !fs || fs->tab != tb) return -EINVAL; + fs->tab = NULL; list_del_init(&fs->ents); mnt_unref_fs(fs); @@ -913,6 +912,9 @@ int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr, struct if (!tb || !itr || !fs) return -EINVAL; + if (fs->tab != tb) + return -ENOENT; + MNT_ITER_INIT(itr, &tb->ents); itr->p = &fs->ents; -- cgit v1.2.3-55-g7522