diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/fs/inode.c x/fs/inode.c --- x-ref/fs/inode.c 2003-12-04 21:19:41.000000000 +0100 +++ x/fs/inode.c 2003-12-04 21:19:44.000000000 +0100 @@ -970,6 +970,20 @@ struct inode * new_inode(struct super_bl return inode; } +void unlock_new_inode(struct inode *inode) +{ + /* + * This is special! We do not need the spinlock + * when clearing I_LOCK, because we're guaranteed + * that nobody else tries to do anything about the + * state of the inode when it is locked, as we + * just created it (so there can be no old holders + * that haven't tested I_LOCK). + */ + inode->i_state &= ~(I_LOCK|I_NEW); + wake_up(&inode->i_wait); +} + /* * This is called without the inode lock held.. Be careful. * @@ -992,31 +1006,13 @@ static struct inode * get_new_inode(stru list_add(&inode->i_list, &inode_in_use); list_add(&inode->i_hash, head); inode->i_ino = ino; - inode->i_state = I_LOCK; + inode->i_state = I_LOCK|I_NEW; spin_unlock(&inode_lock); - /* reiserfs specific hack right here. We don't - ** want this to last, and are looking for VFS changes - ** that will allow us to get rid of it. - ** -- mason@suse.com - */ - if (sb->s_op->read_inode2) { - sb->s_op->read_inode2(inode, opaque) ; - } else { - sb->s_op->read_inode(inode); - } - /* - * This is special! We do not need the spinlock - * when clearing I_LOCK, because we're guaranteed - * that nobody else tries to do anything about the - * state of the inode when it is locked, as we - * just created it (so there can be no old holders - * that haven't tested I_LOCK). + * Return the locked inode with I_NEW set, the + * caller is responsible for filling in the contents */ - inode->i_state &= ~I_LOCK; - wake_up(&inode->i_wait); - return inode; } @@ -1127,8 +1123,7 @@ struct inode *igrab(struct inode *inode) return inode; } - -struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) +struct inode *iget4_locked(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) { struct list_head * head = inode_hashtable + hash(sb,ino); struct inode * inode; diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/linux/fs.h x/include/linux/fs.h --- x-ref/include/linux/fs.h 2003-12-04 21:19:43.000000000 +0100 +++ x/include/linux/fs.h 2003-12-04 21:21:15.000000000 +0100 @@ -990,6 +990,7 @@ struct super_operations { #define I_LOCK 8 #define I_FREEING 16 #define I_CLEAR 32 +#define I_NEW 64 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) @@ -1423,12 +1424,47 @@ extern void force_delete(struct inode *) extern struct inode * igrab(struct inode *); extern struct inode * ilookup(struct super_block *, unsigned long); extern ino_t iunique(struct super_block *, ino_t); +extern void unlock_new_inode(struct inode *); typedef int (*find_inode_t)(struct inode *, unsigned long, void *); -extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *); + +extern struct inode * iget4_locked(struct super_block *, unsigned long, + find_inode_t, void *); + +static inline struct inode *iget4(struct super_block *sb, unsigned long ino, + find_inode_t find_actor, void *opaque) +{ + struct inode *inode = iget4_locked(sb, ino, find_actor, opaque); + + if (inode && (inode->i_state & I_NEW)) { + /* + * reiserfs-specific kludge that is expected to go away ASAP. + */ + if (sb->s_op->read_inode2) + sb->s_op->read_inode2(inode, opaque); + else + sb->s_op->read_inode(inode); + unlock_new_inode(inode); + } + + return inode; +} + static inline struct inode *iget(struct super_block *sb, unsigned long ino) { - return iget4(sb, ino, NULL, NULL); + struct inode *inode = iget4_locked(sb, ino, NULL, NULL); + + if (inode && (inode->i_state & I_NEW)) { + sb->s_op->read_inode(inode); + unlock_new_inode(inode); + } + + return inode; +} + +static inline struct inode *iget_locked(struct super_block *sb, unsigned long ino) +{ + return iget4_locked(sb, ino, NULL, NULL); } extern void clear_inode(struct inode *); diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/kernel/ksyms.c x/kernel/ksyms.c --- x-ref/kernel/ksyms.c 2003-12-04 21:19:43.000000000 +0100 +++ x/kernel/ksyms.c 2003-12-04 21:20:07.000000000 +0100 @@ -153,7 +153,8 @@ EXPORT_SYMBOL(fget); EXPORT_SYMBOL(igrab); EXPORT_SYMBOL(iunique); EXPORT_SYMBOL(ilookup); -EXPORT_SYMBOL(iget4); +EXPORT_SYMBOL(iget4_locked); +EXPORT_SYMBOL(unlock_new_inode); EXPORT_SYMBOL(iput); EXPORT_SYMBOL(inode_init_once); EXPORT_SYMBOL(force_delete);