Date: Fri, 29 Mar 2002 14:34:51 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: Danny Schales <dan@coes.LaTech.edu> Cc: Rolandas Naujikas <rolnas@takas.lt>, Bruce Campbell <bruce@engmail.uwaterloo.ca>, Doug White <dwhite@resnet.uoregon.edu>, Wilko Bulte <wkb@freebie.xs4all.nl>, "Paul Horechuk" <phorechuk@docucom.ca>, stable@FreeBSD.ORG Subject: Re: nfs_fsync: not dirty error in 4.5-RELEASE (possible solution) Message-ID: <200203292234.g2TMYpq67679@apollo.backplane.com>
next in thread | raw e-mail | index | archive | help
Ok, I am putting this back on the main list. After looking at a kernel core that Danny graciously provided, I believe I have located the problem. The core shows NFS panicing on a struct buf showing up on the vnode's v_dirtyblkhd list that is not marked B_DELWRI. After examining the core I found that the buffer was marked B_INVAL, and I found a case in brelse() where B_DELWRI is cleared on a buffer marked B_DELWRI|B_INVAL without moving it out of the vnode's v_dirtyblkhd list. Specifically, line 1214 if kern/vfs_bio.c: /* * If B_INVAL, clear B_DELWRI. We've already placed the buffer * on the correct queue. */ if ((bp->b_flags & (B_INVAL|B_DELWRI)) == (B_INVAL|B_DELWRI)) { bp->b_flags &= ~B_DELWRI; --numdirtybuffers; numdirtywakeup(lodirtybuffers); } I believe that the correct fix is to change this code to: /* * If B_INVAL, clear B_DELWRI. We've already placed the buffer * on the correct queue. */ if ((bp->b_flags & (B_INVAL|B_DELWRI)) == (B_INVAL|B_DELWRI)) bundirty(bp); I would appreciate it if everyone who is able to easily reproduce this panic would test this fix and post your results back to the list. If this solves the problem I will commit it to -current and -stable. -Matt Matthew Dillon <dillon@backplane.com> To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200203292234.g2TMYpq67679>