kern/85163: Giving up on 2 buffers with readonly mounted ext2fs
Don Lewis
truckman at FreeBSD.org
Tue Sep 6 18:02:50 PDT 2005
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
More information about the freebsd-bugs
mailing list