diff options
author | Sage Weil <sage@newdream.net> | 2010-11-16 14:14:34 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-01-12 18:15:12 -0500 |
commit | 6c0f3af72cb1622a66962a1180c36ef8c41be8e2 (patch) | |
tree | 66e415bf31ea31a3e9360c0ce624fd20b6050c89 /fs/ceph/dir.c | |
parent | 3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 (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/dir.c')
-rw-r--r-- | fs/ceph/dir.c | 20 |
1 files changed, 20 insertions, 0 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 | */ | ||
1223 | unsigned 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 | |||
1219 | const struct file_operations ceph_dir_fops = { | 1239 | const struct file_operations ceph_dir_fops = { |
1220 | .read = ceph_read_dir, | 1240 | .read = ceph_read_dir, |
1221 | .readdir = ceph_readdir, | 1241 | .readdir = ceph_readdir, |