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

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