kern/56675: Syncer "giving up" on buffers and ext2 filesystems [still a problem in 5.3RC1]

Don Lewis truckman at FreeBSD.org
Tue Sep 6 17:58:22 PDT 2005


Synopsis: Syncer "giving up" on buffers and ext2 filesystems [still a problem in 5.3RC1]

State-Changed-From-To: open->feedback
State-Changed-By: truckman
State-Changed-When: Wed Sep 7 00:56:49 GMT 2005
State-Changed-Why: 
The following patch 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.163.2.4
diff -u -r1.163.2.4 kern_shutdown.c
--- sys/kern/kern_shutdown.c	7 Jan 2005 20:09:08 -0000	1.163.2.4
+++ sys/kern/kern_shutdown.c	6 Sep 2005 03:28:00 -0000
@@ -249,6 +249,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.
  */
@@ -304,16 +314,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("No buffers busy after final sync");
@@ -359,8 +362,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 (bp->b_dev == NULL) {
 					TAILQ_REMOVE(&mountlist,
 					    bp->b_vp->v_mount, mnt_list);
Index: sys/kern/vfs_bio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.444.2.3
diff -u -r1.444.2.3 vfs_bio.c
--- sys/kern/vfs_bio.c	26 Jun 2005 23:55:50 -0000	1.444.2.3
+++ sys/kern/vfs_bio.c	6 Sep 2005 03:24:06 -0000
@@ -1466,7 +1466,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.167.2.3
diff -u -r1.167.2.3 buf.h
--- sys/sys/buf.h	16 Aug 2005 15:09:44 -0000	1.167.2.3
+++ sys/sys/buf.h	6 Sep 2005 03:34:06 -0000
@@ -205,7 +205,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. */
@@ -232,8 +232,8 @@
 
 #define PRINT_BUF_FLAGS "\20\40b31\37cluster\36vmio\35ram\34b27" \
 	"\33paging\32b25\31writeinprog\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\11persistent\10delwri\7validsuspwrt" \
 	"\6cache\5deferred\4direct\3async\2needcommit\1age"
 
 /*
Index: sys/gnu/ext2fs/fs.h
===================================================================
RCS file: /home/ncvs/src/sys/gnu/ext2fs/Attic/fs.h,v
retrieving revision 1.16.2.1
diff -u -r1.16.2.1 fs.h
--- sys/gnu/ext2fs/fs.h	31 Jan 2005 23:26:02 -0000	1.16.2.1
+++ sys/gnu/ext2fs/fs.h	6 Sep 2005 03:25:01 -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 00:56:49 GMT 2005
Responsible-Changed-Why: 

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


More information about the freebsd-bugs mailing list