aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-11-16 14:14:34 -0500
committerSage Weil <sage@newdream.net>2011-01-12 18:15:12 -0500
commit6c0f3af72cb1622a66962a1180c36ef8c41be8e2 (patch)
tree66e415bf31ea31a3e9360c0ce624fd20b6050c89 /fs/ceph
parent3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 (diff)
ceph: add dir_layout to inode
Add a ceph_dir_layout to the inode, and calculate dentry hash values based on the parent directory's specified dir_hash function. This is needed because the old default Linux dcache hash function is extremely week and leads to a poor distribution of files among dir fragments. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/dir.c20
-rw-r--r--fs/ceph/export.c2
-rw-r--r--fs/ceph/inode.c2
-rw-r--r--fs/ceph/super.h2
4 files changed, 25 insertions, 1 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index d902948a90d8..562f9884a4d9 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -1216,6 +1216,26 @@ void ceph_dentry_lru_del(struct dentry *dn)
1216 } 1216 }
1217} 1217}
1218 1218
1219/*
1220 * Return name hash for a given dentry. This is dependent on
1221 * the parent directory's hash function.
1222 */
1223unsigned ceph_dentry_hash(struct dentry *dn)
1224{
1225 struct inode *dir = dn->d_parent->d_inode;
1226 struct ceph_inode_info *dci = ceph_inode(dir);
1227
1228 switch (dci->i_dir_layout.dl_dir_hash) {
1229 case 0: /* for backward compat */
1230 case CEPH_STR_HASH_LINUX:
1231 return dn->d_name.hash;
1232
1233 default:
1234 return ceph_str_hash(dci->i_dir_layout.dl_dir_hash,
1235 dn->d_name.name, dn->d_name.len);
1236 }
1237}
1238
1219const struct file_operations ceph_dir_fops = { 1239const struct file_operations ceph_dir_fops = {
1220 .read = ceph_read_dir, 1240 .read = ceph_read_dir,
1221 .readdir = ceph_readdir, 1241 .readdir = ceph_readdir,
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 2297d9426992..e41056174bf8 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -59,7 +59,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
59 dout("encode_fh %p connectable\n", dentry); 59 dout("encode_fh %p connectable\n", dentry);
60 cfh->ino = ceph_ino(dentry->d_inode); 60 cfh->ino = ceph_ino(dentry->d_inode);
61 cfh->parent_ino = ceph_ino(parent->d_inode); 61 cfh->parent_ino = ceph_ino(parent->d_inode);
62 cfh->parent_name_hash = parent->d_name.hash; 62 cfh->parent_name_hash = ceph_dentry_hash(parent);
63 *max_len = connected_handle_length; 63 *max_len = connected_handle_length;
64 type = 2; 64 type = 2;
65 } else if (*max_len >= handle_length) { 65 } else if (*max_len >= handle_length) {
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index bf1286588f26..045283ce4413 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -297,6 +297,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
297 ci->i_release_count = 0; 297 ci->i_release_count = 0;
298 ci->i_symlink = NULL; 298 ci->i_symlink = NULL;
299 299
300 memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout));
301
300 ci->i_fragtree = RB_ROOT; 302 ci->i_fragtree = RB_ROOT;
301 mutex_init(&ci->i_fragtree_mutex); 303 mutex_init(&ci->i_fragtree_mutex);
302 304
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 7f01728a4657..6e0826695112 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -239,6 +239,7 @@ struct ceph_inode_info {
239 unsigned i_ceph_flags; 239 unsigned i_ceph_flags;
240 unsigned long i_release_count; 240 unsigned long i_release_count;
241 241
242 struct ceph_dir_layout i_dir_layout;
242 struct ceph_file_layout i_layout; 243 struct ceph_file_layout i_layout;
243 char *i_symlink; 244 char *i_symlink;
244 245
@@ -768,6 +769,7 @@ extern void ceph_dentry_lru_add(struct dentry *dn);
768extern void ceph_dentry_lru_touch(struct dentry *dn); 769extern void ceph_dentry_lru_touch(struct dentry *dn);
769extern void ceph_dentry_lru_del(struct dentry *dn); 770extern void ceph_dentry_lru_del(struct dentry *dn);
770extern void ceph_invalidate_dentry_lease(struct dentry *dentry); 771extern void ceph_invalidate_dentry_lease(struct dentry *dentry);
772extern unsigned ceph_dentry_hash(struct dentry *dn);
771 773
772/* 774/*
773 * our d_ops vary depending on whether the inode is live, 775 * our d_ops vary depending on whether the inode is live,