Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Sep 2005 01:02:49 GMT
From:      Don Lewis <truckman@FreeBSD.org>
To:        hampi@rootshell.be, truckman@FreeBSD.org, freebsd-bugs@FreeBSD.org, truckman@FreeBSD.org
Subject:   Re: kern/85163: Giving up on 2 buffers with readonly mounted ext2fs
Message-ID:  <200509070102.j8712nJv090662@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
Synopsis: Giving up on 2 buffers with readonly mounted ext2fs

State-Changed-From-To: open->feedback
State-Changed-By: truckman
State-Changed-When: Wed Sep 7 01:01:47 GMT 2005
State-Changed-Why: 
The patch below was sent to the PR submitter for testing:

Index: sys/kern/kern_shutdown.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_shutdown.c,v
retrieving revision 1.174
diff -u -r1.174 kern_shutdown.c
--- sys/kern/kern_shutdown.c	12 Apr 2005 05:45:58 -0000	1.174
+++ sys/kern/kern_shutdown.c	5 Sep 2005 19:21:38 -0000
@@ -236,6 +236,16 @@
 	dumpsys(&dumper);
 }
 
+static int
+isbufbusy(struct buf *bp)
+{
+	if (((bp->b_flags & (B_INVAL | B_PERSISTENT)) == 0 &&
+	    BUF_REFCNT(bp) > 0) ||
+	    ((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI))
+		return (1);
+	return (0);
+}
+
 /*
  * Shutdown the system cleanly to prepare for reboot, halt, or power off.
  */
@@ -288,16 +298,9 @@
 		 */
 		for (iter = pbusy = 0; iter < 20; iter++) {
 			nbusy = 0;
-			for (bp = &buf[nbuf]; --bp >= buf; ) {
-				if ((bp->b_flags & B_INVAL) == 0 &&
-				    BUF_REFCNT(bp) > 0) {
+			for (bp = &buf[nbuf]; --bp >= buf; )
+				if (isbufbusy(bp))
 					nbusy++;
-				} else if ((bp->b_flags & (B_DELWRI | B_INVAL))
-						== B_DELWRI) {
-					/* bawrite(bp);*/
-					nbusy++;
-				}
-			}
 			if (nbusy == 0) {
 				if (first_buf_printf)
 					printf("All buffers synced.");
@@ -343,8 +346,7 @@
 		 */
 		nbusy = 0;
 		for (bp = &buf[nbuf]; --bp >= buf; ) {
-			if (((bp->b_flags&B_INVAL) == 0 && BUF_REFCNT(bp)) ||
-			    ((bp->b_flags & (B_DELWRI|B_INVAL)) == B_DELWRI)) {
+			if (isbufbusy(bp)) {
 #if 0
 /* XXX: This is bogus.  We should probably have a BO_REMOTE flag instead */
 				if (bp->b_dev == NULL) {
Index: sys/kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.493
diff -u -r1.493 vfs_bio.c
--- sys/kern/vfs_bio.c	3 Aug 2005 05:02:08 -0000	1.493
+++ sys/kern/vfs_bio.c	5 Sep 2005 07:46:49 -0000
@@ -1365,7 +1365,8 @@
 	if (bp->b_bufsize || bp->b_kvasize)
 		bufspacewakeup();
 
-	bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF | B_DIRECT);
+	bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF | B_DIRECT |
+	    B_PERSISTENT);
 	if ((bp->b_flags & B_DELWRI) == 0 && (bp->b_xflags & BX_VNDIRTY))
 		panic("brelse: not dirty");
 	/* unlock */
Index: sys/sys/buf.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/buf.h,v
retrieving revision 1.188
diff -u -r1.188 buf.h
--- sys/sys/buf.h	13 Aug 2005 20:21:33 -0000	1.188
+++ sys/sys/buf.h	5 Sep 2005 19:36:24 -0000
@@ -195,7 +195,7 @@
 #define	B_CACHE		0x00000020	/* Bread found us in the cache. */
 #define	B_VALIDSUSPWRT	0x00000040	/* Valid write during suspension. */
 #define	B_DELWRI	0x00000080	/* Delay I/O until buffer reused. */
-#define	B_00000100	0x00000100	/* Available flag. */
+#define	B_PERSISTENT	0x00000100	/* Perm. ref'ed while fs mounted. */
 #define	B_DONE		0x00000200	/* I/O completed. */
 #define	B_EINTR		0x00000400	/* I/O was interrupted */
 #define	B_00000800	0x00000800	/* Available flag. */
@@ -220,10 +220,10 @@
 #define B_CLUSTER	0x40000000	/* pagein op, so swap() can count it */
 #define B_REMFREE	0x80000000	/* Delayed bremfree */
 
-#define PRINT_BUF_FLAGS "\20\40b31\37cluster\36vmio\35ram\34b27" \
+#define PRINT_BUF_FLAGS "\20\40remfree\37cluster\36vmio\35ram\34b27" \
 	"\33paging\32b25\31b24\30b23\27relbuf\26dirty\25b20" \
-	"\24b19\23phys\22clusterok\21malloc\20nocache\17locked\16inval" \
-	"\15scanned\14nowdrain\13eintr\12done\11b8\10delwri\7validsuspwrt" \
+	"\24b19\23b18\22clusterok\21malloc\20nocache\17b14\16inval" \
+	"\15b12\14b11\13eintr\12done\11persist\10delwri\7validsuspwrt" \
 	"\6cache\5deferred\4direct\3async\2needcommit\1age"
 
 /*
Index: sys/gnu/fs/ext2fs/fs.h
===================================================================
RCS file: /home/ncvs/src/sys/gnu/fs/ext2fs/fs.h,v
retrieving revision 1.17
diff -u -r1.17 fs.h
--- sys/gnu/fs/ext2fs/fs.h	6 Jan 2005 18:27:30 -0000	1.17
+++ sys/gnu/fs/ext2fs/fs.h	5 Sep 2005 21:29:11 -0000
@@ -150,11 +150,16 @@
 
 /*
  * Historically, ext2fs kept it's metadata buffers on the LOCKED queue.  Now,
- * we simply change the lock owner to kern so that it may be released from
- * another context.  Later, we release the buffer, and conditionally write it
- * when we're done.
+ * we simply change the lock owner to kern so that we may use it from contexts
+ * other than the one that originally locked it.  When we are finished with
+ * the buffer, we release it, writing it first if it was dirty.  The
+ * B_PERSISTENT flag is cleared by brelse(), which bwrite() calls after the
+ * buffer is written in the B_DIRTY case.
  */
-#define LCK_BUF(bp)	BUF_KERNPROC(bp);
+#define LCK_BUF(bp) { \
+	(bp)->b_flags |= B_PERSISTENT; \
+	BUF_KERNPROC(bp); \
+}
 
 #define ULCK_BUF(bp) { \
 	long flags; \




Responsible-Changed-From-To: freebsd-bugs->truckman
Responsible-Changed-By: truckman
Responsible-Changed-When: Wed Sep 7 01:01:47 GMT 2005
Responsible-Changed-Why: 

http://www.freebsd.org/cgi/query-pr.cgi?pr=85163



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509070102.j8712nJv090662>