From: William Lee Irwin III <wli@holomorphy.com>
To: Kirill Korotaev <kk@sw.ru>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Invalidate_inodes can be very slow
Date: Mon, 13 Oct 2003 04:06:53 -0700 [thread overview]
Message-ID: <20031013110653.GG16158@holomorphy.com> (raw)
In-Reply-To: <200310131446.25921.kk@sw.ru>
At some point in the past, I wrote:
>> Untested brute-force forward port to 2.6.0-test7-bk4. No idea if the
>> locking is correct or if list movement is done in all needed places.
On Mon, Oct 13, 2003 at 02:46:25PM +0400, Kirill Korotaev wrote:
> First of all, thanks for forward port. I think this patch is quite usefull
> for both 2.4 and 2.6 kernels, but I can't check it on all kernels myself.
> comments:
> 1. why have you replaced list_del with list_del_init in my patch?
> It's not required.
> 2. locks are ok, as for i_list, i_hash lists.
> 3. Missed
> +list_add(&inode->i_sb_list, &sb->s_inodes);
> in get_new_inode_fast() function. Please add it.
> I looked through, everything else looks ok.
> [your patch]
list_del_init() was for consistency with the surrounding ->i_list
deletions, hence erring on the side of caution.
Amended patch below, addressing point 3.
diff -prauN linux-2.6.0-test7-bk4/fs/inode.c inode-2.6.0-test7-bk4-1/fs/inode.c
--- linux-2.6.0-test7-bk4/fs/inode.c 2003-10-08 12:24:51.000000000 -0700
+++ inode-2.6.0-test7-bk4-1/fs/inode.c 2003-10-13 03:44:06.000000000 -0700
@@ -285,7 +285,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;
@@ -298,13 +298,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_list);
+ list_del(&inode->i_sb_list);
list_add(&inode->i_list, dispose);
inode->i_state |= I_FREEING;
count++;
@@ -340,10 +338,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);
@@ -443,6 +438,7 @@ static void prune_icache(int nr_to_scan)
continue;
}
hlist_del_init(&inode->i_hash);
+ list_del_init(&inode->i_sb_list);
list_move(&inode->i_list, &freeable);
inode->i_state |= I_FREEING;
nr_pruned++;
@@ -553,6 +549,7 @@ struct inode *new_inode(struct super_blo
spin_lock(&inode_lock);
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
+ list_add(&inode->i_sb_list, &sb->s_inodes);
inode->i_ino = ++last_ino;
inode->i_state = 0;
spin_unlock(&inode_lock);
@@ -601,6 +598,7 @@ static struct inode * get_new_inode(stru
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
+ list_add(&inode->i_sb_list, &sb->s_inodes);
hlist_add_head(&inode->i_hash, head);
inode->i_state = I_LOCK|I_NEW;
spin_unlock(&inode_lock);
@@ -649,6 +647,7 @@ static struct inode * get_new_inode_fast
inode->i_ino = ino;
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
+ list_add(&inode->i_sb_list, &sb->s_inodes);
hlist_add_head(&inode->i_hash, head);
inode->i_state = I_LOCK|I_NEW;
spin_unlock(&inode_lock);
@@ -984,6 +983,7 @@ void generic_delete_inode(struct inode *
struct super_operations *op = inode->i_sb->s_op;
list_del_init(&inode->i_list);
+ list_del_init(&inode->i_sb_list);
inode->i_state|=I_FREEING;
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
@@ -1031,6 +1031,7 @@ static void generic_forget_inode(struct
hlist_del_init(&inode->i_hash);
}
list_del_init(&inode->i_list);
+ list_del_init(&inode->i_sb_list);
inode->i_state|=I_FREEING;
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
@@ -1228,27 +1229,11 @@ void remove_dquot_ref(struct super_block
return; /* nothing to do */
spin_lock(&inode_lock); /* This lock is for inodes code */
/* We don't have to lock against quota code - test IS_QUOTAINIT is just for speedup... */
-
- list_for_each(act_head, &inode_in_use) {
- inode = list_entry(act_head, struct inode, i_list);
- if (inode->i_sb == sb && IS_QUOTAINIT(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_QUOTAINIT(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_QUOTAINIT(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)
if (IS_QUOTAINIT(inode))
remove_inode_dquot_ref(inode, type, &tofree_head);
- }
+
spin_unlock(&inode_lock);
put_dquot_list(&tofree_head);
diff -prauN linux-2.6.0-test7-bk4/fs/super.c inode-2.6.0-test7-bk4-1/fs/super.c
--- linux-2.6.0-test7-bk4/fs/super.c 2003-10-08 12:24:04.000000000 -0700
+++ inode-2.6.0-test7-bk4-1/fs/super.c 2003-10-13 02:28:22.000000000 -0700
@@ -66,6 +66,7 @@ static struct super_block *alloc_super(v
INIT_LIST_HEAD(&s->s_files);
INIT_LIST_HEAD(&s->s_instances);
INIT_HLIST_HEAD(&s->s_anon);
+ INIT_LIST_HEAD(&s->s_inodes);
init_rwsem(&s->s_umount);
sema_init(&s->s_lock, 1);
down_write(&s->s_umount);
diff -prauN linux-2.6.0-test7-bk4/include/linux/fs.h inode-2.6.0-test7-bk4-1/include/linux/fs.h
--- linux-2.6.0-test7-bk4/include/linux/fs.h 2003-10-08 12:24:03.000000000 -0700
+++ inode-2.6.0-test7-bk4-1/include/linux/fs.h 2003-10-13 02:37:13.000000000 -0700
@@ -369,6 +369,7 @@ struct block_device {
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;
@@ -687,6 +688,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 */
next prev parent reply other threads:[~2003-10-13 11:04 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-13 9:18 [PATCH] Invalidate_inodes can be very slow Kirill Korotaev
2003-10-13 9:53 ` William Lee Irwin III
2003-10-13 10:46 ` Kirill Korotaev
2003-10-13 11:06 ` William Lee Irwin III [this message]
2003-10-13 11:08 ` Andrew Morton
2003-10-13 11:19 ` William Lee Irwin III
2003-10-13 11:45 ` Kirill Korotaev
2003-10-13 11:54 ` William Lee Irwin III
2003-10-13 12:02 ` Kirill Korotaev
2003-10-13 12:11 ` William Lee Irwin III
2003-10-13 12:21 ` Kirill Korotaev
2003-10-13 12:29 ` Nikita Danilov
2003-10-13 13:08 ` Kirill Korotaev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20031013110653.GG16158@holomorphy.com \
--to=wli@holomorphy.com \
--cc=kk@sw.ru \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.