--- buffer.c.~1~ Thu Sep 2 10:14:10 1999 +++ linux/fs/buffer.c Fri Sep 3 17:26:23 1999 @@ -898,19 +898,21 @@ */ void __bforget(struct buffer_head * buf) { + /* grab the lru lock here to block kswapd. */ spin_lock(&lru_list_lock); write_lock(&hash_table_lock); - if (atomic_read(&buf->b_count) != 1 || buffer_locked(buf)) { - touch_buffer(buf); - atomic_dec(&buf->b_count); - } else { - atomic_set(&buf->b_count, 0); - buf->b_state = 0; - if (buf->b_pprev) - __hash_unlink(buf); - __remove_from_lru_list(buf, buf->b_list); - put_last_free(buf); - } + if (!atomic_dec_and_test(&buf->b_count) || buffer_locked(buf)) + goto in_use; + if (buf->b_pprev) + __hash_unlink(buf); + write_unlock(&hash_table_lock); + __remove_from_lru_list(buf, buf->b_list); + spin_unlock(&lru_list_lock); + buf->b_state = 0; + put_last_free(buf); + return; + + in_use: write_unlock(&hash_table_lock); spin_unlock(&lru_list_lock); }