Blame SOURCES/autofs-5.1.6-add-a-hash-index-to-mnt_list.patch

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