public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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);

             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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox