From 4a798872c7c86444f0201ffa330168f6a33be5f0 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh-Weinraub Date: Sun, 20 Jan 2008 23:22:02 +0200 Subject: [PATCH] hash inodes only when required. This fixes hang that occurs when searching for an inode with a hash value that equals to the hash value of the root inode. Also added default implementation for getattr. --- src/kernel/client.c | 3 ++- src/kernel/dir.c | 2 +- src/kernel/inode.c | 21 ++++++++++++++++++++- src/kernel/super.c | 2 ++ src/kernel/super.h | 5 +++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/kernel/client.c b/src/kernel/client.c index 3839f60af8ec5..1d07e8a3c4b92 100644 --- a/src/kernel/client.c +++ b/src/kernel/client.c @@ -110,13 +110,14 @@ static int open_root_inode(struct ceph_client *client, struct ceph_mount_args *a err = -EINVAL; goto out; } - + if (client->sb->s_root == NULL) { /* get the fs root inode. Note that this is not necessarily the root of the mount */ err = ceph_get_inode(client->sb, le64_to_cpu(rinfo.trace_in[0].in->ino), &root_inode); if (err < 0) goto out; + alloc_fs = 1; client->sb->s_root = d_alloc_root(root_inode); diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 3216d6bdae3e8..273d44587047f 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -533,7 +533,7 @@ ceph_dir_create(struct inode *dir, struct dentry *dentry, int mode, const struct inode_operations ceph_dir_iops = { .lookup = ceph_dir_lookup, -// .getattr = ceph_inode_getattr, + .getattr = ceph_inode_getattr, .setattr = ceph_setattr, .mknod = ceph_dir_mknod, .symlink = ceph_dir_symlink, diff --git a/src/kernel/inode.c b/src/kernel/inode.c index cc4f5487cf1c6..6a1f1b9de175d 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -16,6 +16,8 @@ const struct inode_operations ceph_symlink_iops; int ceph_get_inode(struct super_block *sb, unsigned long ino, struct inode **pinode) { + struct ceph_inode_info *ci; + BUG_ON(pinode == NULL); *pinode = iget_locked(sb, ino); @@ -24,6 +26,10 @@ int ceph_get_inode(struct super_block *sb, unsigned long ino, struct inode **pin if ((*pinode)->i_state & I_NEW) unlock_new_inode(*pinode); + ci = ceph_inode(*pinode); + + ci->i_hashval = ino; + return 0; } @@ -46,7 +52,10 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info) inode->i_rdev = le32_to_cpu(info->rdev); inode->i_blocks = 1; - insert_inode_hash(inode); + if (ci->i_hashval != inode->i_ino) { + insert_inode_hash(inode); + ci->i_hashval = inode->i_ino; + } dout(30, "fill_inode %p ino=%lx by %d.%d sz=%llu mode %o nlink %d\n", inode, inode->i_ino, inode->i_uid, inode->i_gid, inode->i_size, inode->i_mode, @@ -574,3 +583,13 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) return 0; } +int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + dout(30, "ceph_inode_getattr\n"); + + /* TODO: need to revalidate first */ + generic_fillattr(dentry->d_inode, stat); + stat->blksize = CEPH_BLKSIZE; + return 0; +} + diff --git a/src/kernel/super.c b/src/kernel/super.c index 0f7766e9a70d4..3ba2db095837b 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -122,6 +122,8 @@ static struct inode *ceph_alloc_inode(struct super_block *sb) ci->i_wr_size = 0; ci->i_wr_mtime.tv_sec = 0; ci->i_wr_mtime.tv_nsec = 0; + + ci->i_hashval = 0; return &ci->vfs_inode; } diff --git a/src/kernel/super.h b/src/kernel/super.h index 726ce8b520ff6..c42853f2d09e6 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -22,6 +22,8 @@ extern int ceph_debug_osdc; #define CEPH_SUPER_MAGIC 0xc364c0de /* whatev */ +#define CEPH_BLKSIZE 4096 + /* * mount options */ @@ -129,6 +131,8 @@ struct ceph_inode_info { loff_t i_wr_size; struct timespec i_wr_mtime; struct timespec i_old_atime; + + unsigned long i_hashval; struct inode vfs_inode; /* at end */ }; @@ -224,6 +228,7 @@ extern void ceph_remove_caps(struct ceph_inode_info *ci); extern int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, struct ceph_mds_session *session); extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); +extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); /* addr.c */ extern const struct address_space_operations ceph_aops; -- 2.39.5