From: Andrew Morton <akpm@zip.com.au>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: "Stephen C. Tweedie" <sct@redhat.com>,
lkml <linux-kernel@vger.kernel.org>
Subject: [patch] remove buffer_head.b_inode
Date: Wed, 28 Nov 2001 19:38:48 -0800 [thread overview]
Message-ID: <3C05ADC8.23503BFC@zip.com.au> (raw)
It's only ever used as a boolean, so we can use the list_emptiness
of buffer_head.b_inode_buffers for the same thing.
This code does assume that a list_del on an empty list_head
is safe - I think Red Hat kernels have a list_head poisoning
trick which will explode over this. Easily fixed, if desired.
--- linux-2.5.1-pre3/fs/buffer.c Wed Nov 28 15:54:42 2001
+++ 25/fs/buffer.c Wed Nov 28 19:26:19 2001
@@ -574,38 +574,32 @@ struct buffer_head * get_hash_table(kdev
return bh;
}
-void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
+static inline void
+__buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
{
- spin_lock(&lru_list_lock);
- if (bh->b_inode)
- list_del(&bh->b_inode_buffers);
- bh->b_inode = inode;
+ list_del(&bh->b_inode_buffers);
list_add(&bh->b_inode_buffers, &inode->i_dirty_buffers);
- spin_unlock(&lru_list_lock);
}
-void buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode)
+void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
{
spin_lock(&lru_list_lock);
- if (bh->b_inode)
- list_del(&bh->b_inode_buffers);
- bh->b_inode = inode;
- list_add(&bh->b_inode_buffers, &inode->i_dirty_data_buffers);
+ __buffer_insert_inode_queue(bh, inode);
spin_unlock(&lru_list_lock);
}
-/* The caller must have the lru_list lock before calling the
- remove_inode_queue functions. */
-static void __remove_inode_queue(struct buffer_head *bh)
+void buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode)
{
- bh->b_inode = NULL;
+ spin_lock(&lru_list_lock);
list_del(&bh->b_inode_buffers);
+ list_add(&bh->b_inode_buffers, &inode->i_dirty_data_buffers);
+ spin_unlock(&lru_list_lock);
}
-static inline void remove_inode_queue(struct buffer_head *bh)
+/* lru_list_lock must be held */
+static inline void __remove_inode_queue(struct buffer_head *bh)
{
- if (bh->b_inode)
- __remove_inode_queue(bh);
+ list_del_init(&bh->b_inode_buffers);
}
int inode_has_buffers(struct inode *inode)
@@ -690,7 +684,7 @@ void invalidate_bdev(struct block_device
printk("invalidate: dirty buffer\n");
if (!atomic_read(&bh->b_count)) {
if (destroy_dirty_buffers || !buffer_dirty(bh)) {
- remove_inode_queue(bh);
+ __remove_inode_queue(bh);
}
} else
printk("invalidate: busy buffer\n");
@@ -831,12 +825,9 @@ int fsync_inode_buffers(struct inode *in
while (!list_empty(&inode->i_dirty_buffers)) {
bh = BH_ENTRY(inode->i_dirty_buffers.next);
- list_del(&bh->b_inode_buffers);
- if (!buffer_dirty(bh) && !buffer_locked(bh))
- bh->b_inode = NULL;
- else {
- bh->b_inode = &tmp;
- list_add(&bh->b_inode_buffers, &tmp.i_dirty_buffers);
+ __remove_inode_queue(bh);
+ if (buffer_dirty(bh) || buffer_locked(bh)) {
+ __buffer_insert_inode_queue(bh, &tmp);
if (buffer_dirty(bh)) {
get_bh(bh);
spin_unlock(&lru_list_lock);
@@ -849,7 +840,7 @@ int fsync_inode_buffers(struct inode *in
while (!list_empty(&tmp.i_dirty_buffers)) {
bh = BH_ENTRY(tmp.i_dirty_buffers.prev);
- remove_inode_queue(bh);
+ __remove_inode_queue(bh);
get_bh(bh);
spin_unlock(&lru_list_lock);
wait_on_buffer(bh);
@@ -880,12 +871,9 @@ int fsync_inode_data_buffers(struct inod
while (!list_empty(&inode->i_dirty_data_buffers)) {
bh = BH_ENTRY(inode->i_dirty_data_buffers.next);
- list_del(&bh->b_inode_buffers);
- if (!buffer_dirty(bh) && !buffer_locked(bh))
- bh->b_inode = NULL;
- else {
- bh->b_inode = &tmp;
- list_add(&bh->b_inode_buffers, &tmp.i_dirty_data_buffers);
+ __remove_inode_queue(bh);
+ if (buffer_dirty(bh) || buffer_locked(bh)) {
+ __buffer_insert_inode_queue(bh, &tmp);
if (buffer_dirty(bh)) {
get_bh(bh);
spin_unlock(&lru_list_lock);
@@ -898,7 +886,7 @@ int fsync_inode_data_buffers(struct inod
while (!list_empty(&tmp.i_dirty_data_buffers)) {
bh = BH_ENTRY(tmp.i_dirty_data_buffers.prev);
- remove_inode_queue(bh);
+ __remove_inode_queue(bh);
get_bh(bh);
spin_unlock(&lru_list_lock);
wait_on_buffer(bh);
@@ -998,9 +986,9 @@ void invalidate_inode_buffers(struct ino
spin_lock(&lru_list_lock);
while ((entry = inode->i_dirty_buffers.next) != &inode->i_dirty_buffers)
- remove_inode_queue(BH_ENTRY(entry));
+ __remove_inode_queue(BH_ENTRY(entry));
while ((entry = inode->i_dirty_data_buffers.next) != &inode->i_dirty_data_buffers)
- remove_inode_queue(BH_ENTRY(entry));
+ __remove_inode_queue(BH_ENTRY(entry));
spin_unlock(&lru_list_lock);
}
@@ -1126,7 +1114,7 @@ static void __refile_buffer(struct buffe
__remove_from_lru_list(bh);
bh->b_list = dispose;
if (dispose == BUF_CLEAN)
- remove_inode_queue(bh);
+ __remove_inode_queue(bh);
__insert_into_lru_list(bh, dispose);
}
}
@@ -1189,7 +1177,7 @@ struct buffer_head * bread(kdev_t dev, i
*/
static void __put_unused_buffer_head(struct buffer_head * bh)
{
- if (bh->b_inode)
+ if (!list_empty(&bh->b_inode_buffers))
BUG();
if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) {
kmem_cache_free(bh_cachep, bh);
@@ -1219,7 +1207,7 @@ EXPORT_SYMBOL(put_unused_buffer_head);
*/
struct buffer_head * get_unused_buffer_head(int async)
{
- struct buffer_head * bh;
+ struct buffer_head *bh;
spin_lock(&unused_list_lock);
if (nr_unused_buffer_heads > NR_RESERVED) {
@@ -1227,7 +1215,7 @@ struct buffer_head * get_unused_buffer_h
unused_list = bh->b_next_free;
nr_unused_buffer_heads--;
spin_unlock(&unused_list_lock);
- return bh;
+ goto ret_bh;
}
spin_unlock(&unused_list_lock);
@@ -1238,7 +1226,7 @@ struct buffer_head * get_unused_buffer_h
if((bh = kmem_cache_alloc(bh_cachep, SLAB_NOFS)) != NULL) {
bh->b_blocknr = -1;
bh->b_this_page = NULL;
- return bh;
+ goto ret_bh;
}
/*
@@ -1251,12 +1239,15 @@ struct buffer_head * get_unused_buffer_h
unused_list = bh->b_next_free;
nr_unused_buffer_heads--;
spin_unlock(&unused_list_lock);
- return bh;
+ goto ret_bh;
}
spin_unlock(&unused_list_lock);
}
return NULL;
+ret_bh:
+ INIT_LIST_HEAD(&bh->b_inode_buffers);
+ return bh;
}
EXPORT_SYMBOL(get_unused_buffer_head);
@@ -2390,7 +2381,7 @@ cleaned_buffers_try_again:
if (p->b_dev == B_FREE) BUG();
- remove_inode_queue(p);
+ __remove_inode_queue(p);
__remove_from_queues(p);
__put_unused_buffer_head(p);
} while (tmp != bh);
--- linux-2.5.1-pre3/include/linux/fs.h Wed Nov 28 15:54:42 2001
+++ 25/include/linux/fs.h Wed Nov 28 19:26:19 2001
@@ -261,8 +261,9 @@ struct buffer_head {
wait_queue_head_t b_wait;
- struct inode * b_inode;
- struct list_head b_inode_buffers; /* doubly linked list of inode dirty buffers */
+ /* Dirty buffers against an inode. Must be in list_empty()
+ * state when this buffer is not on an inode's i_dirty_buffers */
+ struct list_head b_inode_buffers;
};
typedef void (bh_end_io_t)(struct buffer_head *bh, int uptodate);
next reply other threads:[~2001-11-29 3:39 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-11-29 3:38 Andrew Morton [this message]
-- strict thread matches above, loose matches on Subject: below --
2002-04-24 8:52 [patch] remove buffer_head.b_inode Andrew Morton
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=3C05ADC8.23503BFC@zip.com.au \
--to=akpm@zip.com.au \
--cc=linux-kernel@vger.kernel.org \
--cc=sct@redhat.com \
--cc=torvalds@transmeta.com \
/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.