autofs/SOURCES/autofs-5.1.6-add-a-hash-ind...

203 lines
4.3 KiB
Diff

autofs-5.1.6 - add a hash index to mnt_list
From: Ian Kent <raven@themaw.net>
Add a hash index (and utility functions) to struct mnt_list.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 8 +++
lib/mounts.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -121,6 +121,7 @@ xx/xx/2018 autofs-5.1.5
- change mountpoint to mp in struct ext_mount.
- make external mounts independent of amd_entry.
- make external mounts use simpler hashtable.
+- add a hash index to mnt_list.
19/12/2017 autofs-5.1.4
- fix spec file url.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -54,10 +54,16 @@ struct mapent;
struct mnt_list {
char *mp;
unsigned int flags;
+
+ /* Hash of all mounts */
+ struct hlist_node hash;
+ unsigned int ref;
+
/*
* List operations ie. get_mnt_list.
*/
struct mnt_list *next;
+
/*
* Tree operations ie. tree_make_tree,
* tree_get_mnt_list etc.
@@ -100,6 +106,8 @@ char *make_mnt_name_string(char *path);
int ext_mount_add(const char *, const char *);
int ext_mount_remove(const char *);
int ext_mount_inuse(const char *);
+struct mnt_list *mnts_lookup_mount(const char *mp);
+void mnts_put_mount(struct mnt_list *mnt);
struct mnt_list *get_mnt_list(const char *path, int include);
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
void free_mnt_list(struct mnt_list *list);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -63,6 +63,11 @@ struct ext_mount {
static DEFINE_HASHTABLE(ext_mounts_hash, EXT_MOUNTS_HASH_BITS);
static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define MNTS_HASH_BITS 7
+
+static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS);
+static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
+
unsigned int linux_version_code(void)
{
struct utsname my_utsname;
@@ -832,6 +837,136 @@ done:
return ret;
}
+static void mnts_hash_mutex_lock(void)
+{
+ int status = pthread_mutex_lock(&mnts_hash_mutex);
+ if (status)
+ fatal(status);
+}
+
+static void mnts_hash_mutex_unlock(void)
+{
+ int status = pthread_mutex_unlock(&mnts_hash_mutex);
+ if (status)
+ fatal(status);
+}
+
+static struct mnt_list *mnts_lookup(const char *mp)
+{
+ uint32_t hval = hash(mp, HASH_SIZE(mnts_hash));
+ struct mnt_list *this;
+
+ if (hlist_empty(&mnts_hash[hval]))
+ return NULL;
+
+ hlist_for_each_entry(this, &mnts_hash[hval], hash) {
+ if (!strcmp(this->mp, mp) && this->ref)
+ return this;
+ }
+
+ return NULL;
+}
+
+static struct mnt_list *mnts_alloc_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = malloc(sizeof(*this));
+ if (!this)
+ goto done;
+ memset(this, 0, sizeof(*this));
+
+ this->mp = strdup(mp);
+ if (!this->mp) {
+ free(this);
+ this = NULL;
+ goto done;
+ }
+
+ this->ref = 1;
+ INIT_HLIST_NODE(&this->hash);
+done:
+ return this;
+}
+
+static void __mnts_get_mount(struct mnt_list *mnt)
+{
+ mnt->ref++;
+}
+
+static void __mnts_put_mount(struct mnt_list *mnt)
+{
+ mnt->ref--;
+ if (!mnt->ref) {
+ hash_del(&mnt->hash);
+ free(mnt->mp);
+ free(mnt);
+ }
+}
+
+static struct mnt_list *mnts_new_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = mnts_lookup(mp);
+ if (this) {
+ __mnts_get_mount(this);
+ goto done;
+ }
+
+ this = mnts_alloc_mount(mp);
+ if (!this)
+ goto done;
+
+ hash_add_str(mnts_hash, &this->hash, this->mp);
+done:
+ return this;
+}
+
+static struct mnt_list *mnts_get_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = mnts_lookup(mp);
+ if (this) {
+ __mnts_get_mount(this);
+ return this;
+ }
+
+ return mnts_new_mount(mp);
+}
+
+static struct mnt_list *__mnts_lookup_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ this = mnts_lookup(mp);
+ if (this)
+ __mnts_get_mount(this);
+
+ return this;
+}
+
+struct mnt_list *mnts_lookup_mount(const char *mp)
+{
+ struct mnt_list *this;
+
+ mnts_hash_mutex_lock();
+ this = __mnts_lookup_mount(mp);
+ mnts_hash_mutex_unlock();
+
+ return this;
+}
+
+void mnts_put_mount(struct mnt_list *mnt)
+{
+ if (!mnt)
+ return;
+ mnts_hash_mutex_lock();
+ __mnts_put_mount(mnt);
+ mnts_hash_mutex_unlock();
+}
+
/* From glibc decode_name() */
/* Since the values in a line are separated by spaces, a name cannot
* contain a space. Therefore some programs encode spaces in names