All of lore.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 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.