Date: Sat, 11 Jul 2015 19:11:41 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r285402 - in stable/10/sys: kern sys ufs/ffs Message-ID: <201507111911.t6BJBf3K057341@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sat Jul 11 19:11:40 2015 New Revision: 285402 URL: https://svnweb.freebsd.org/changeset/base/285402 Log: MFC r284887: Handle errors from background write of the cylinder group blocks. MFC r284927: Simplify code. Approved by: re (gjb) Modified: stable/10/sys/kern/vfs_bio.c stable/10/sys/sys/buf.h stable/10/sys/ufs/ffs/ffs_vfsops.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/kern/vfs_bio.c ============================================================================== --- stable/10/sys/kern/vfs_bio.c Sat Jul 11 19:07:47 2015 (r285401) +++ stable/10/sys/kern/vfs_bio.c Sat Jul 11 19:11:40 2015 (r285402) @@ -1566,6 +1566,12 @@ brelse(struct buf *bp) return; } + if ((bp->b_vflags & (BV_BKGRDINPROG | BV_BKGRDERR)) == BV_BKGRDERR) { + BO_LOCK(bp->b_bufobj); + bp->b_vflags &= ~BV_BKGRDERR; + BO_UNLOCK(bp->b_bufobj); + bdirty(bp); + } if (bp->b_iocmd == BIO_WRITE && (bp->b_ioflags & BIO_ERROR) && bp->b_error == EIO && !(bp->b_flags & B_INVAL)) { /* @@ -1822,7 +1828,11 @@ bqrelse(struct buf *bp) } /* buffers with stale but valid contents */ - if (bp->b_flags & B_DELWRI) { + if ((bp->b_flags & B_DELWRI) != 0 || (bp->b_vflags & (BV_BKGRDINPROG | + BV_BKGRDERR)) == BV_BKGRDERR) { + BO_LOCK(bp->b_bufobj); + bp->b_vflags &= ~BV_BKGRDERR; + BO_UNLOCK(bp->b_bufobj); qindex = QUEUE_DIRTY; } else { if ((bp->b_flags & B_DELWRI) == 0 && @@ -2341,6 +2351,16 @@ restart: continue; } + /* + * Requeue the background write buffer with error. + */ + if ((bp->b_vflags & BV_BKGRDERR) != 0) { + bremfreel(bp); + mtx_unlock(&bqclean); + bqrelse(bp); + continue; + } + KASSERT(bp->b_qindex == qindex, ("getnewbuf: inconsistent queue %d bp %p", qindex, bp)); Modified: stable/10/sys/sys/buf.h ============================================================================== --- stable/10/sys/sys/buf.h Sat Jul 11 19:07:47 2015 (r285401) +++ stable/10/sys/sys/buf.h Sat Jul 11 19:11:40 2015 (r285402) @@ -248,8 +248,9 @@ struct buf { #define BV_SCANNED 0x00000001 /* VOP_FSYNC funcs mark written bufs */ #define BV_BKGRDINPROG 0x00000002 /* Background write in progress */ #define BV_BKGRDWAIT 0x00000004 /* Background write waiting */ +#define BV_BKGRDERR 0x00000008 /* Error from background write */ -#define PRINT_BUF_VFLAGS "\20\3bkgrdwait\2bkgrdinprog\1scanned" +#define PRINT_BUF_VFLAGS "\20\4bkgrderr\3bkgrdwait\2bkgrdinprog\1scanned" #ifdef _KERNEL /* Modified: stable/10/sys/ufs/ffs/ffs_vfsops.c ============================================================================== --- stable/10/sys/ufs/ffs/ffs_vfsops.c Sat Jul 11 19:07:47 2015 (r285401) +++ stable/10/sys/ufs/ffs/ffs_vfsops.c Sat Jul 11 19:11:40 2015 (r285402) @@ -1977,12 +1977,19 @@ ffs_backgroundwritedone(struct buf *bp) BO_LOCK(bufobj); if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL) panic("backgroundwritedone: lost buffer"); + + /* + * We should mark the cylinder group buffer origbp as + * dirty, to not loose the failed write. + */ + if ((bp->b_ioflags & BIO_ERROR) != 0) + origbp->b_vflags |= BV_BKGRDERR; BO_UNLOCK(bufobj); /* * Process dependencies then return any unfinished ones. */ pbrelvp(bp); - if (!LIST_EMPTY(&bp->b_dep)) + if (!LIST_EMPTY(&bp->b_dep) && (bp->b_ioflags & BIO_ERROR) == 0) buf_complete(bp); #ifdef SOFTUPDATES if (!LIST_EMPTY(&bp->b_dep)) @@ -1994,6 +2001,15 @@ ffs_backgroundwritedone(struct buf *bp) */ bp->b_flags |= B_NOCACHE; bp->b_flags &= ~B_CACHE; + + /* + * Prevent brelse() from trying to keep and re-dirtying bp on + * errors. It causes b_bufobj dereference in + * bdirty()/reassignbuf(), and b_bufobj was cleared in + * pbrelvp() above. + */ + if ((bp->b_ioflags & BIO_ERROR) != 0) + bp->b_flags |= B_INVAL; bufdone(bp); BO_LOCK(bufobj); /* @@ -2055,6 +2071,7 @@ ffs_bufwrite(struct buf *bp) if (bp->b_vflags & BV_BKGRDINPROG) panic("bufwrite: still writing"); } + bp->b_vflags &= ~BV_BKGRDERR; BO_UNLOCK(bp->b_bufobj); /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507111911.t6BJBf3K057341>