summaryrefslogtreecommitdiff
path: root/drivers/dax/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dax/super.c')
-rw-r--r--drivers/dax/super.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index e84070b55463..d182d46aea0f 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -15,6 +15,7 @@
#include <linux/uio.h>
#include <linux/dax.h>
#include <linux/fs.h>
+#include <linux/jhash.h>
#include "dax-private.h"
static dev_t dax_devt;
@@ -28,6 +29,38 @@ static struct super_block *dax_superblock __read_mostly;
static struct hlist_head dax_host_list[DAX_HASH_SIZE];
static DEFINE_SPINLOCK(dax_host_lock);
+static u32 dax_inode_key_hash_fn(const void *data, u32 len, u32 seed)
+{
+ const dev_t *devt = data;
+
+ return jhash(devt, sizeof(*devt), seed);
+}
+
+static u32 dax_inode_obj_hash_fn(const void *obj, u32 len, u32 seed)
+{
+ const struct inode *inode = obj;
+
+ return jhash(&inode->i_rdev, sizeof(inode->i_rdev), seed);
+}
+
+static int dax_inode_hash_cmp_fn(struct rhashtable_compare_arg *arg,
+ const void *obj)
+{
+ const struct inode *inode = obj;
+ const dev_t *devt = arg->key;
+
+ if (inode->i_rdev == *devt)
+ return 0;
+ return 1;
+}
+
+static const struct rhashtable_params dax_inode_table_params = {
+ .head_offset = offsetof(struct inode, i_hash),
+ .hashfn = dax_inode_key_hash_fn,
+ .obj_hashfn = dax_inode_obj_hash_fn,
+ .obj_cmpfn = dax_inode_hash_cmp_fn,
+};
+
int dax_read_lock(void)
{
return srcu_read_lock(&dax_srcu);
@@ -513,18 +546,11 @@ static struct file_system_type dax_fs_type = {
.kill_sb = kill_anon_super,
};
-static int dax_test(struct inode *inode, void *data)
+static int dax_set(struct inode *inode, const void *data)
{
- dev_t devt = *(dev_t *) data;
-
- return inode->i_rdev == devt;
-}
+ const dev_t *devt = data;
-static int dax_set(struct inode *inode, void *data)
-{
- dev_t devt = *(dev_t *) data;
-
- inode->i_rdev = devt;
+ inode->i_rdev = *devt;
return 0;
}
@@ -533,8 +559,7 @@ static struct dax_device *dax_dev_get(dev_t devt)
struct dax_device *dax_dev;
struct inode *inode;
- inode = iget5_locked(dax_superblock, hash_32(devt + DAXFS_MAGIC, 31),
- dax_test, dax_set, &devt);
+ inode = iget5_locked(dax_superblock, dax_set, &devt);
if (!inode)
return NULL;
@@ -711,8 +736,14 @@ static int dax_fs_init(void)
}
dax_superblock = dax_mnt->mnt_sb;
+ rc = super_setup_inode_table(dax_superblock, &dax_inode_table_params);
+ if (rc)
+ goto err_itable;
+
return 0;
+ err_itable:
+ kern_unmount(dax_mnt);
err_mount:
kmem_cache_destroy(dax_cache);