]) # LIBCFS_GET_USER_PAGES_6ARG
#
+# LIBCFS_STRINGHASH
+#
+# 4.6 kernel created stringhash.h which moved stuff out of dcache.h
+# commit f4bcbe792b8f434e32487cff9d9e30ab45a3ce02
+#
+AC_DEFUN([LIBCFS_STRINGHASH], [
+LB_CHECK_LINUX_HEADER([linux/stringhash.h], [
+ AC_DEFINE(HAVE_STRINGHASH, 1,
+ [stringhash.h is present])])
+]) # LIBCFS_STRINGHASH
+
+#
# LIBCFS_STACKTRACE_OPS
#
# Kernel version 4.8 commit c8fe4609827aedc9c4b45de80e7cdc8ccfa8541b
]) # LIBCFS_SCHED_HEADERS
#
+# Kernel version 4.11 commit f9fe1c12d126f9887441fa5bb165046f30ddd4b5
+# introduced rhashtable_lookup_get_insert_fast
+#
+AC_DEFUN([LIBCFS_RHASHTABLE_LOOKUP_GET_INSERT_FAST], [
+LB_CHECK_COMPILE([if 'rhashtable_lookup_get_insert_fast' exist],
+rhashtable_lookup_get_insert_fast, [
+ #include <linux/rhashtable.h>
+],[
+ const struct rhashtable_params params = { 0 };
+ void *ret;
+
+ ret = rhashtable_lookup_get_insert_fast(NULL, NULL, params);
+],[
+ AC_DEFINE(HAVE_RHASHTABLE_LOOKUP_GET_INSERT_FAST, 1,
+ [rhashtable_lookup_get_insert_fast() is available])
+])
+]) # LIBCFS_RHASHTABLE_LOOKUP_GET_INSERT_FAST
+
+#
# LIBCFS_WAIT_QUEUE_ENTRY
#
# Kernel version 4.13 ac6424b981bce1c4bc55675c6ce11bfe1bbfa64f
# 4.6
LIBCFS_STACKTRACE_OPS_ADDRESS_RETURN_INT
LIBCFS_GET_USER_PAGES_6ARG
+LIBCFS_STRINGHASH
# 4.8
LIBCFS_STACKTRACE_OPS
# 4.9
# 4.10
LIBCFS_HOTPLUG_STATE_MACHINE
# 4.11
+LIBCFS_RHASHTABLE_LOOKUP_GET_INSERT_FAST
LIBCFS_SCHED_HEADERS
# 4.13
LIBCFS_WAIT_QUEUE_ENTRY
EXTRA_DIST = linux-misc.h linux-fs.h linux-mem.h linux-time.h linux-cpu.h \
- linux-list.h linux-crypto.h
+ linux-list.h linux-hash.h linux-crypto.h
--- /dev/null
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+
+#ifndef __LIBCFS_LINUX_HASH_H__
+#define __LIBCFS_LINUX_HASH_H__
+
+#include <linux/dcache.h>
+#include <linux/rhashtable.h>
+
+u64 cfs_hashlen_string(const void *salt, const char *name);
+
+#ifndef hashlen_hash
+#define hashlen_hash(hashlen) ((u32)(hashlen))
+#endif
+
+#ifndef HAVE_STRINGHASH
+#ifndef hashlen_create
+#define hashlen_create(hash, len) ((u64)(len)<<32 | (u32)(hash))
+#endif
+#endif /* !HAVE_STRINGHASH */
+
+#ifndef HAVE_RHASHTABLE_LOOKUP_GET_INSERT_FAST
+/**
+ * rhashtable_lookup_get_insert_fast - lookup and insert object into hash table
+ * @ht: hash table
+ * @obj: pointer to hash head inside object
+ * @params: hash table parameters
+ *
+ * Just like rhashtable_lookup_insert_fast(), but this function returns the
+ * object if it exists, NULL if it did not and the insertion was successful,
+ * and an ERR_PTR otherwise.
+ */
+static inline void *rhashtable_lookup_get_insert_fast(
+ struct rhashtable *ht, struct rhash_head *obj,
+ const struct rhashtable_params params)
+{
+ const char *key;
+ void *ret;
+ int rc;
+
+ rc = rhashtable_lookup_insert_fast(ht, obj, params);
+ switch (rc) {
+ case -EEXIST:
+ key = rht_obj(ht, obj);
+ ret = rhashtable_lookup_fast(ht, key, params);
+ break;
+ case 0:
+ ret = NULL;
+ break;
+ default:
+ ret = ERR_PTR(rc);
+ break;
+ }
+ return ret;
+}
+#endif /* !HAVE_RHASHTABLE_LOOKUP_GET_INSERT_FAST */
+
+#endif /* __LIBCFS_LINUX_MISC_H__ */
libcfs-linux-objs := linux-tracefile.o linux-debug.o
libcfs-linux-objs += linux-prim.o
libcfs-linux-objs += linux-curproc.o
+libcfs-linux-objs += linux-hash.o
libcfs-linux-objs += linux-module.o
libcfs-linux-objs += linux-crypto.o linux-crypto-adler.o
@HAVE_CRC32_TRUE@libcfs-linux-objs += linux-crypto-crc32.o
EXTRA_DIST = linux-debug.c linux-prim.c linux-tracefile.c \
- linux-curproc.c linux-module.c \
+ linux-curproc.c linux-module.c linux-hash.c \
linux-crypto.c linux-crypto-crc32.c linux-crypto-adler.c\
linux-crypto-crc32pclmul.c linux-crypto-crc32c-pclmul.c \
crc32-pclmul_asm.S crc32c-pcl-intel-asm_64.S inst.h
--- /dev/null
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/module.h>
+#ifdef HAVE_STRINGHASH
+#include <linux/stringhash.h>
+#else
+#include <linux/dcache.h>
+#endif
+#include <linux/hash.h>
+
+#include <libcfs/linux/linux-hash.h>
+
+/* Return the "hash_len" (hash and length) of a null-terminated string */
+/* The kernel equivalent is in fs/namei.c but for some strange reason
+ * RHEL7.5 stuck it in dax/super.c instead. This placement never existed
+ * upstream so to make life easier we just have the equavilent
+ */
+u64 cfs_hashlen_string(const void *salt, const char *name)
+{
+#ifdef HAVE_FULL_NAME_HASH_3ARGS
+ unsigned long hash = init_name_hash(salt);
+#else
+ unsigned long hash = init_name_hash();
+#endif
+ unsigned long len = 0, c;
+
+ c = (unsigned char)*name;
+ while (c) {
+ len++;
+ hash = partial_name_hash(c, hash);
+ c = (unsigned char)name[len];
+ }
+ return hashlen_create(end_name_hash(hash), len);
+}
+EXPORT_SYMBOL(cfs_hashlen_string);