--- ./include/linux/fs.h.invl 2004-08-14 14:55:09.000000000 +0400 +++ ./include/linux/fs.h 2004-09-08 18:47:46.989249792 +0400 @@ -419,6 +419,7 @@ static inline int mapping_writably_mappe struct inode { struct hlist_node i_hash; struct list_head i_list; + struct list_head i_sb_list; struct list_head i_dentry; unsigned long i_ino; atomic_t i_count; @@ -750,6 +751,7 @@ struct super_block { atomic_t s_active; void *s_security; + struct list_head s_inodes; /* all inodes */ struct list_head s_dirty; /* dirty inodes */ struct list_head s_io; /* parked for writeback */ struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ --- ./fs/hugetlbfs/inode.c.invl 2004-08-14 14:56:14.000000000 +0400 +++ ./fs/hugetlbfs/inode.c 2004-09-08 19:17:05.787871760 +0400 @@ -198,6 +198,7 @@ static void hugetlbfs_delete_inode(struc struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb); hlist_del_init(&inode->i_hash); + list_del(&inode->i_sb_list); list_del_init(&inode->i_list); inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; @@ -240,6 +241,7 @@ static void hugetlbfs_forget_inode(struc inodes_stat.nr_unused--; hlist_del_init(&inode->i_hash); out_truncate: + list_del(&inode->i_sb_list); list_del_init(&inode->i_list); inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; --- ./fs/inode.c.invl 2004-09-08 18:35:48.082540224 +0400 +++ ./fs/inode.c 2004-09-08 18:57:45.873205592 +0400 @@ -295,7 +295,7 @@ static void dispose_list(struct list_hea /* * Invalidate all inodes for a device. */ -static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose) +static int invalidate_list(struct list_head *head, struct list_head * dispose) { struct list_head *next; int busy = 0, count = 0; @@ -308,12 +308,11 @@ static int invalidate_list(struct list_h next = next->next; if (tmp == head) break; - inode = list_entry(tmp, struct inode, i_list); - if (inode->i_sb != sb) - continue; + inode = list_entry(tmp, struct inode, i_sb_list); invalidate_inode_buffers(inode); if (!atomic_read(&inode->i_count)) { hlist_del_init(&inode->i_hash); + list_del(&inode->i_sb_list); list_move(&inode->i_list, dispose); inode->i_state |= I_FREEING; count++; @@ -349,10 +348,7 @@ int invalidate_inodes(struct super_block down(&iprune_sem); spin_lock(&inode_lock); - busy = invalidate_list(&inode_in_use, sb, &throw_away); - busy |= invalidate_list(&inode_unused, sb, &throw_away); - busy |= invalidate_list(&sb->s_dirty, sb, &throw_away); - busy |= invalidate_list(&sb->s_io, sb, &throw_away); + busy = invalidate_list(&sb->s_inodes, &throw_away); spin_unlock(&inode_lock); dispose_list(&throw_away); @@ -452,6 +448,7 @@ static void prune_icache(int nr_to_scan) continue; } hlist_del_init(&inode->i_hash); + list_del(&inode->i_sb_list); list_move(&inode->i_list, &freeable); inode->i_state |= I_FREEING; nr_pruned++; @@ -561,6 +558,7 @@ struct inode *new_inode(struct super_blo if (inode) { spin_lock(&inode_lock); inodes_stat.nr_inodes++; + list_add(&inode->i_sb_list, &sb->s_inodes); list_add(&inode->i_list, &inode_in_use); inode->i_ino = ++last_ino; inode->i_state = 0; @@ -609,6 +607,7 @@ static struct inode * get_new_inode(stru goto set_failed; inodes_stat.nr_inodes++; + list_add(&inode->i_sb_list, &sb->s_inodes); list_add(&inode->i_list, &inode_in_use); hlist_add_head(&inode->i_hash, head); inode->i_state = I_LOCK|I_NEW; @@ -657,6 +656,7 @@ static struct inode * get_new_inode_fast if (!old) { inode->i_ino = ino; inodes_stat.nr_inodes++; + list_add(&inode->i_sb_list, &sb->s_inodes); list_add(&inode->i_list, &inode_in_use); hlist_add_head(&inode->i_hash, head); inode->i_state = I_LOCK|I_NEW; @@ -993,6 +993,7 @@ void generic_delete_inode(struct inode * { struct super_operations *op = inode->i_sb->s_op; + list_del(&inode->i_sb_list); list_del_init(&inode->i_list); inode->i_state|=I_FREEING; inodes_stat.nr_inodes--; @@ -1038,6 +1039,7 @@ static void generic_forget_inode(struct inodes_stat.nr_unused--; hlist_del_init(&inode->i_hash); } + list_del(&inode->i_sb_list); list_del_init(&inode->i_list); inode->i_state|=I_FREEING; inodes_stat.nr_inodes--; @@ -1230,33 +1232,15 @@ int remove_inode_dquot_ref(struct inode void remove_dquot_ref(struct super_block *sb, int type, struct list_head *tofree_head) { struct inode *inode; - struct list_head *act_head; if (!sb->dq_op) return; /* nothing to do */ - spin_lock(&inode_lock); /* This lock is for inodes code */ + spin_lock(&inode_lock); /* This lock is for inodes code */ /* We hold dqptr_sem so we are safe against the quota code */ - list_for_each(act_head, &inode_in_use) { - inode = list_entry(act_head, struct inode, i_list); - if (inode->i_sb == sb && !IS_NOQUOTA(inode)) - remove_inode_dquot_ref(inode, type, tofree_head); - } - list_for_each(act_head, &inode_unused) { - inode = list_entry(act_head, struct inode, i_list); - if (inode->i_sb == sb && !IS_NOQUOTA(inode)) - remove_inode_dquot_ref(inode, type, tofree_head); - } - list_for_each(act_head, &sb->s_dirty) { - inode = list_entry(act_head, struct inode, i_list); - if (!IS_NOQUOTA(inode)) - remove_inode_dquot_ref(inode, type, tofree_head); - } - list_for_each(act_head, &sb->s_io) { - inode = list_entry(act_head, struct inode, i_list); + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) if (!IS_NOQUOTA(inode)) remove_inode_dquot_ref(inode, type, tofree_head); - } spin_unlock(&inode_lock); } --- ./fs/super.c.invl 2004-08-14 14:55:22.000000000 +0400 +++ ./fs/super.c 2004-09-08 18:46:47.227334984 +0400 @@ -65,6 +65,7 @@ static struct super_block *alloc_super(v } INIT_LIST_HEAD(&s->s_dirty); INIT_LIST_HEAD(&s->s_io); + INIT_LIST_HEAD(&s->s_inodes); INIT_LIST_HEAD(&s->s_files); INIT_LIST_HEAD(&s->s_instances); INIT_HLIST_HEAD(&s->s_anon);