linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Viro <viro@math.psu.edu>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH] inode dirty blocks  Re: test12-pre4
Date: Mon, 4 Dec 2000 01:01:36 -0500 (EST)	[thread overview]
Message-ID: <Pine.GSO.4.21.0012040054400.5055-100000@weyl.math.psu.edu> (raw)
In-Reply-To: <Pine.LNX.4.10.10012031828170.22914-100000@penguin.transmeta.com>



On Sun, 3 Dec 2000, Linus Torvalds wrote:

> 
> Synching up with Alan and various other stuff. The most important one
> being the fix to the inode dirty block list.

It doesn't solve the problem. If you unlink a file with dirty metadata
you have a nice chance to hit the BUG() in inode.c:83. I hope that patch
below closes all remaining holes. See analysis in previous posting
(basically, bforget() is not enough when we free the block; bh should
be removed from the inode's list regardless of the ->b_count).
							Cheers,
								Al

diff -urN rc12-pre4/fs/buffer.c rc12-pre4-dirty_blocks/fs/buffer.c
--- rc12-pre4/fs/buffer.c	Mon Dec  4 01:01:43 2000
+++ rc12-pre4-dirty_blocks/fs/buffer.c	Mon Dec  4 01:11:42 2000
@@ -1164,6 +1164,31 @@
 }
 
 /*
+ * Call it when you are going to free the block. The difference between
+ * that and bforget() is that we remove the thing from inode queue
+ * unconditionally.
+ */
+void bforget_inode(struct buffer_head * buf)
+{
+	/* grab the lru lock here to block bdflush. */
+	spin_lock(&lru_list_lock);
+	write_lock(&hash_table_lock);
+	remove_inode_queue(buf);
+	if (!atomic_dec_and_test(&buf->b_count) || buffer_locked(buf))
+		goto in_use;
+	__hash_unlink(buf);
+	write_unlock(&hash_table_lock);
+	__remove_from_lru_list(buf, buf->b_list);
+	spin_unlock(&lru_list_lock);
+	put_last_free(buf);
+	return;
+
+ in_use:
+	write_unlock(&hash_table_lock);
+	spin_unlock(&lru_list_lock);
+}
+
+/*
  * bread() reads a specified block and returns the buffer that contains
  * it. It returns NULL if the block was unreadable.
  */
@@ -1460,6 +1485,9 @@
 		clear_bit(BH_Mapped, &bh->b_state);
 		clear_bit(BH_Req, &bh->b_state);
 		clear_bit(BH_New, &bh->b_state);
+		spin_lock(&lru_list_lock);
+		remove_inode_queue(bh);
+		spin_unlock(&lru_list_lock);
 	}
 }
 
diff -urN rc12-pre4/fs/ext2/inode.c rc12-pre4-dirty_blocks/fs/ext2/inode.c
--- rc12-pre4/fs/ext2/inode.c	Mon Dec  4 01:01:43 2000
+++ rc12-pre4-dirty_blocks/fs/ext2/inode.c	Mon Dec  4 01:13:10 2000
@@ -416,7 +416,7 @@
 
 	/* Allocation failed, free what we already allocated */
 	for (i = 1; i < n; i++)
-		bforget(branch[i].bh);
+		bforget_inode(branch[i].bh);
 	for (i = 0; i < n; i++)
 		ext2_free_blocks(inode, le32_to_cpu(branch[i].key), 1);
 	return err;
@@ -484,7 +484,7 @@
 
 changed:
 	for (i = 1; i < num; i++)
-		bforget(where[i].bh);
+		bforget_inode(where[i].bh);
 	for (i = 0; i < num; i++)
 		ext2_free_blocks(inode, le32_to_cpu(where[i].key), 1);
 	return -EAGAIN;
@@ -854,7 +854,7 @@
 					   (u32*)bh->b_data,
 					   (u32*)bh->b_data + addr_per_block,
 					   depth);
-			bforget(bh);
+			bforget_inode(bh);
 			/* Writer: ->i_blocks */
 			inode->i_blocks -= inode->i_sb->s_blocksize / 512;
 			/* Writer: end */
diff -urN rc12-pre4/include/linux/fs.h rc12-pre4-dirty_blocks/include/linux/fs.h
--- rc12-pre4/include/linux/fs.h	Mon Dec  4 01:01:47 2000
+++ rc12-pre4-dirty_blocks/include/linux/fs.h	Mon Dec  4 01:12:03 2000
@@ -1201,6 +1201,7 @@
 		__brelse(buf);
 }
 extern void __bforget(struct buffer_head *);
+extern void bforget_inode(struct buffer_head *);
 static inline void bforget(struct buffer_head *buf)
 {
 	if (buf)
diff -urN rc12-pre4/kernel/ksyms.c rc12-pre4-dirty_blocks/kernel/ksyms.c
--- rc12-pre4/kernel/ksyms.c	Mon Dec  4 01:01:49 2000
+++ rc12-pre4-dirty_blocks/kernel/ksyms.c	Mon Dec  4 01:12:19 2000
@@ -188,6 +188,7 @@
 EXPORT_SYMBOL(breada);
 EXPORT_SYMBOL(__brelse);
 EXPORT_SYMBOL(__bforget);
+EXPORT_SYMBOL(bforget_inode);
 EXPORT_SYMBOL(ll_rw_block);
 EXPORT_SYMBOL(__wait_on_buffer);
 EXPORT_SYMBOL(___wait_on_page);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

  parent reply	other threads:[~2000-12-04  6:32 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-12-04  2:29 test12-pre4 Linus Torvalds
2000-12-04  3:57 ` test12-pre4 Mohammad A. Haque
2000-12-04  8:03   ` test12-pre4 Jeff Garzik
2000-12-04 12:25     ` test12-pre4 Alan Cox
2000-12-04 12:21   ` test12-pre4 Alan Cox
2000-12-04 20:22     ` test12-pre4 Nikhil Goel
2000-12-04  6:01 ` Alexander Viro [this message]
2000-12-04 13:25   ` [PATCH] inode dirty blocks test12-pre4 Andrew Morton
2000-12-04 13:49     ` [PATCH] inode dirty blocks Alexander Viro
2000-12-05  1:47       ` Andrew Morton
2000-12-05  2:41         ` Linus Torvalds
2000-12-05  3:31           ` Alexander Viro
2000-12-05  3:52             ` Linus Torvalds
2000-12-05  4:19               ` Alexander Viro
2000-12-05  2:49         ` Mohammad A. Haque
2000-12-05  4:15           ` Peter Samuelson
2000-12-04 18:16   ` [PATCH] inode dirty blocks Re: test12-pre4 Stephen C. Tweedie
2000-12-04 19:54     ` Alexander Viro
2000-12-05 20:35   ` 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=Pine.GSO.4.21.0012040054400.5055-100000@weyl.math.psu.edu \
    --to=viro@math.psu.edu \
    --cc=linux-kernel@vger.kernel.org \
    --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;
as well as URLs for NNTP newsgroup(s).