diff -u --recursive --new-file v2.2.10/linux/fs/inode.c linux/fs/inode.c --- v2.2.10/linux/fs/inode.c Tue May 4 19:57:12 1999 +++ linux/fs/inode.c Fri Sep 10 15:59:07 1999 @@ -44,7 +44,7 @@ * allowing for low-overhead inode sync() operations. */ -static LIST_HEAD(inode_in_use); +LIST_HEAD(inode_in_use); static LIST_HEAD(inode_unused); static struct list_head inode_hashtable[HASH_SIZE]; @@ -296,6 +296,7 @@ INIT_LIST_HEAD(&inode->i_hash); list_del(&inode->i_list); list_add(&inode->i_list, dispose); + inode->i_state |= I_FREEING; continue; } busy = 1; @@ -356,6 +357,7 @@ list_del(&INODE(tmp)->i_hash); INIT_LIST_HEAD(&INODE(tmp)->i_hash); list_add(tmp, freeable); + list_entry(tmp, struct inode, i_list)->i_state = I_FREEING; found = 1; } @@ -639,6 +641,43 @@ return tmp & HASH_MASK; } +/* Yeah, I know about quadratic hash. Maybe, later. */ +ino_t iunique(struct super_block *sb, ino_t max_reserved) +{ + static ino_t counter = 0; + struct inode *inode; + struct list_head * head; + ino_t res; + spin_lock(&inode_lock); +retry: + if (counter > max_reserved) { + head = inode_hashtable + hash(sb,counter); + inode = find_inode(sb, res = counter++, head); + if (!inode) { + spin_unlock(&inode_lock); + return res; + } + inode->i_count--; /* compensate find_inode() */ + } else { + counter = max_reserved + 1; + } + goto retry; + +} + +struct inode *igrab(struct inode *inode) +{ + spin_lock(&inode_lock); + if (inode->i_state & I_FREEING) + inode = NULL; + else + inode->i_count++; + spin_unlock(&inode_lock); + if (inode) + wait_on_inode(inode); + return inode; +} + struct inode *iget(struct super_block *sb, unsigned long ino) { struct list_head * head = inode_hashtable + hash(sb,ino); @@ -692,6 +731,7 @@ INIT_LIST_HEAD(&inode->i_hash); list_del(&inode->i_list); INIT_LIST_HEAD(&inode->i_list); + inode->i_state|=I_FREEING; if (op && op->delete_inode) { void (*delete)(struct inode *) = op->delete_inode; spin_unlock(&inode_lock); @@ -702,6 +742,7 @@ if (list_empty(&inode->i_hash)) { list_del(&inode->i_list); INIT_LIST_HEAD(&inode->i_list); + inode->i_state|=I_FREEING; spin_unlock(&inode_lock); clear_inode(inode); spin_lock(&inode_lock); diff -u --recursive --new-file v2.2.10/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.2.10/linux/fs/nfs/dir.c Sun May 9 08:18:22 1999 +++ linux/fs/nfs/dir.c Fri Sep 10 15:59:03 1999 @@ -463,6 +463,8 @@ /* Filehandle matches? */ if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) { + if (!list_empty(&dentry->d_subdirs)) + shrink_dcache_parent(dentry); if (dentry->d_count < 2) goto out_bad; } diff -u --recursive --new-file v2.2.10/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.2.10/linux/include/linux/fs.h Tue May 11 19:35:44 1999 +++ linux/include/linux/fs.h Fri Sep 10 16:00:51 1999 @@ -829,6 +829,8 @@ #define lnamei(pathname) __namei(pathname, 0) extern void iput(struct inode *); +extern struct inode * igrab(struct inode *inode); +extern ino_t iunique(struct super_block *, ino_t); extern struct inode * iget(struct super_block *, unsigned long); extern void clear_inode(struct inode *); extern struct inode * get_empty_inode(void); diff -u --recursive --new-file v2.2.10/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.2.10/linux/kernel/ksyms.c Fri Apr 30 00:06:32 1999 +++ linux/kernel/ksyms.c Fri Sep 10 15:59:07 1999 @@ -38,6 +38,7 @@ #include #include #include +#include #if defined(CONFIG_PROC_FS) #include @@ -116,6 +117,8 @@ EXPORT_SYMBOL(get_fs_type); EXPORT_SYMBOL(getname); EXPORT_SYMBOL(__fput); +EXPORT_SYMBOL(igrab); +EXPORT_SYMBOL(iunique); EXPORT_SYMBOL(iget); EXPORT_SYMBOL(iput); EXPORT_SYMBOL(__namei);