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 | |
| 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')
| -rw-r--r-- | fs/ceph/dir.c | 20 | ||||
| -rw-r--r-- | fs/ceph/export.c | 2 | ||||
| -rw-r--r-- | fs/ceph/inode.c | 2 | ||||
| -rw-r--r-- | fs/ceph/super.h | 2 |
4 files changed, 25 insertions, 1 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index d902948a90d..562f9884a4d 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, |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 2297d942699..e41056174bf 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 bf1286588f2..045283ce441 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 7f01728a465..6e082669511 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); | |||
| 768 | extern void ceph_dentry_lru_touch(struct dentry *dn); | 769 | extern void ceph_dentry_lru_touch(struct dentry *dn); |
| 769 | extern void ceph_dentry_lru_del(struct dentry *dn); | 770 | extern void ceph_dentry_lru_del(struct dentry *dn); |
| 770 | extern void ceph_invalidate_dentry_lease(struct dentry *dentry); | 771 | extern void ceph_invalidate_dentry_lease(struct dentry *dentry); |
| 772 | extern 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, |
