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>