Commit 9b406173 authored by Jan Harkes's avatar Jan Harkes Committed by Linus Torvalds

[PATCH] iget_locked [6/6]

As of the last patch the inode_hashtable doesn't really need to be
indexed by i_ino anymore, the only reason we still have to keep the
hashvalue and i_ino identical is because of insert_inode_hash.

If at some point a FS specific getattr method is implemented it will be
possible to completely remove any use of i_ino by the VFS.
parent aa624c8d
...@@ -74,16 +74,17 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid, ...@@ -74,16 +74,17 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
struct inode *inode; struct inode *inode;
struct coda_inode_info *cii; struct coda_inode_info *cii;
struct coda_sb_info *sbi = coda_sbp(sb); struct coda_sb_info *sbi = coda_sbp(sb);
ino_t ino = coda_f2i(fid); unsigned long hash = coda_f2i(fid);
inode = iget5_locked(sb, ino, coda_test_inode, coda_set_inode, fid); inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid);
if (!inode) if (!inode)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (inode->i_state & I_NEW) { if (inode->i_state & I_NEW) {
cii = ITOC(inode); cii = ITOC(inode);
inode->i_ino = ino; /* we still need to set i_ino for things like stat(2) */
inode->i_ino = hash;
list_add(&cii->c_cilist, &sbi->sbi_cihead); list_add(&cii->c_cilist, &sbi->sbi_cihead);
unlock_new_inode(inode); unlock_new_inode(inode);
} }
...@@ -124,6 +125,7 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, ...@@ -124,6 +125,7 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
struct ViceFid *newfid) struct ViceFid *newfid)
{ {
struct coda_inode_info *cii; struct coda_inode_info *cii;
unsigned long hash = coda_f2i(newfid);
cii = ITOC(inode); cii = ITOC(inode);
...@@ -134,23 +136,22 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, ...@@ -134,23 +136,22 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
/* XXX we probably need to hold some lock here! */ /* XXX we probably need to hold some lock here! */
remove_inode_hash(inode); remove_inode_hash(inode);
cii->c_fid = *newfid; cii->c_fid = *newfid;
inode->i_ino = coda_f2i(newfid); inode->i_ino = hash;
insert_inode_hash(inode); __insert_inode_hash(inode, hash);
} }
/* convert a fid to an inode. */ /* convert a fid to an inode. */
struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
{ {
ino_t nr;
struct inode *inode; struct inode *inode;
unsigned long hash = coda_f2i(fid);
if ( !sb ) { if ( !sb ) {
printk("coda_fid_to_inode: no sb!\n"); printk("coda_fid_to_inode: no sb!\n");
return NULL; return NULL;
} }
nr = coda_f2i(fid); inode = iget5_locked(sb, hash, coda_test_inode, coda_fail_inode, fid);
inode = iget5_locked(sb, nr, coda_test_inode, coda_fail_inode, fid);
if ( !inode ) if ( !inode )
return NULL; return NULL;
......
...@@ -635,9 +635,9 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct list_hea ...@@ -635,9 +635,9 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct list_hea
return inode; return inode;
} }
static inline unsigned long hash(struct super_block *sb, unsigned long i_ino) static inline unsigned long hash(struct super_block *sb, unsigned long hashval)
{ {
unsigned long tmp = i_ino + ((unsigned long) sb / L1_CACHE_BYTES); unsigned long tmp = hashval + ((unsigned long) sb / L1_CACHE_BYTES);
tmp = tmp + (tmp >> I_HASHBITS); tmp = tmp + (tmp >> I_HASHBITS);
return tmp & I_HASHMASK; return tmp & I_HASHMASK;
} }
...@@ -703,9 +703,9 @@ struct inode *igrab(struct inode *inode) ...@@ -703,9 +703,9 @@ struct inode *igrab(struct inode *inode)
* the filesystem gets back a new locked and hashed inode and gets * the filesystem gets back a new locked and hashed inode and gets
* to fill it in before unlocking it via unlock_new_inode(). * to fill it in before unlocking it via unlock_new_inode().
*/ */
struct inode *iget5_locked(struct super_block *sb, unsigned long ino, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data) struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
{ {
struct list_head * head = inode_hashtable + hash(sb,ino); struct list_head * head = inode_hashtable + hash(sb, hashval);
struct inode * inode; struct inode * inode;
spin_lock(&inode_lock); spin_lock(&inode_lock);
...@@ -759,18 +759,20 @@ EXPORT_SYMBOL(iget_locked); ...@@ -759,18 +759,20 @@ EXPORT_SYMBOL(iget_locked);
EXPORT_SYMBOL(unlock_new_inode); EXPORT_SYMBOL(unlock_new_inode);
/** /**
* insert_inode_hash - hash an inode * __insert_inode_hash - hash an inode
* @inode: unhashed inode * @inode: unhashed inode
* @hashval: unsigned long value used to locate this object in the
* inode_hashtable.
* *
* Add an inode to the inode hash for this superblock. If the inode * Add an inode to the inode hash for this superblock. If the inode
* has no superblock it is added to a separate anonymous chain. * has no superblock it is added to a separate anonymous chain.
*/ */
void insert_inode_hash(struct inode *inode) void __insert_inode_hash(struct inode *inode, unsigned long hashval)
{ {
struct list_head *head = &anon_hash_chain; struct list_head *head = &anon_hash_chain;
if (inode->i_sb) if (inode->i_sb)
head = inode_hashtable + hash(inode->i_sb, inode->i_ino); head = inode_hashtable + hash(inode->i_sb, hashval);
spin_lock(&inode_lock); spin_lock(&inode_lock);
list_add(&inode->i_hash, head); list_add(&inode->i_hash, head);
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
......
...@@ -641,7 +641,7 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) ...@@ -641,7 +641,7 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
fattr: fattr fattr: fattr
}; };
struct inode *inode = NULL; struct inode *inode = NULL;
unsigned long ino; unsigned long hash;
if ((fattr->valid & NFS_ATTR_FATTR) == 0) if ((fattr->valid & NFS_ATTR_FATTR) == 0)
goto out_no_inode; goto out_no_inode;
...@@ -651,9 +651,9 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) ...@@ -651,9 +651,9 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
goto out_no_inode; goto out_no_inode;
} }
ino = nfs_fattr_to_ino_t(fattr); hash = nfs_fattr_to_ino_t(fattr);
if (!(inode = iget5_locked(sb, ino, nfs_find_actor, nfs_init_locked, &desc))) if (!(inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc)))
goto out_no_inode; goto out_no_inode;
if (inode->i_state & I_NEW) { if (inode->i_state & I_NEW) {
...@@ -661,7 +661,9 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) ...@@ -661,7 +661,9 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
loff_t new_isize; loff_t new_isize;
time_t new_atime; time_t new_atime;
inode->i_ino = ino; /* We set i_ino for the few things that still rely on it,
* such as stat(2) */
inode->i_ino = hash;
/* We can't support UPDATE_ATIME(), since the server will reset it */ /* We can't support UPDATE_ATIME(), since the server will reset it */
inode->i_flags |= S_NOATIME; inode->i_flags |= S_NOATIME;
......
...@@ -1221,8 +1221,13 @@ extern void __iget(struct inode * inode); ...@@ -1221,8 +1221,13 @@ extern void __iget(struct inode * inode);
extern void clear_inode(struct inode *); extern void clear_inode(struct inode *);
extern struct inode *new_inode(struct super_block *); extern struct inode *new_inode(struct super_block *);
extern void remove_suid(struct dentry *); extern void remove_suid(struct dentry *);
extern void insert_inode_hash(struct inode *);
extern void __insert_inode_hash(struct inode *, unsigned long hashval);
extern void remove_inode_hash(struct inode *); extern void remove_inode_hash(struct inode *);
static inline void insert_inode_hash(struct inode *inode) {
__insert_inode_hash(inode, inode->i_ino);
}
extern struct file * get_empty_filp(void); extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list); extern void file_move(struct file *f, struct list_head *list);
extern void ll_rw_block(int, int, struct buffer_head * bh[]); extern void ll_rw_block(int, int, struct buffer_head * bh[]);
......
...@@ -537,7 +537,7 @@ EXPORT_SYMBOL(clear_inode); ...@@ -537,7 +537,7 @@ EXPORT_SYMBOL(clear_inode);
EXPORT_SYMBOL(init_special_inode); EXPORT_SYMBOL(init_special_inode);
EXPORT_SYMBOL(__get_hash_table); EXPORT_SYMBOL(__get_hash_table);
EXPORT_SYMBOL(new_inode); EXPORT_SYMBOL(new_inode);
EXPORT_SYMBOL(insert_inode_hash); EXPORT_SYMBOL(__insert_inode_hash);
EXPORT_SYMBOL(remove_inode_hash); EXPORT_SYMBOL(remove_inode_hash);
EXPORT_SYMBOL(buffer_insert_list); EXPORT_SYMBOL(buffer_insert_list);
EXPORT_SYMBOL(make_bad_inode); EXPORT_SYMBOL(make_bad_inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment