On Thu, Jan 31, 2019 at 04:26:45PM -0500, Ted Unangst wrote: > Instead, we note that the write failed and mark a flag in the vnode. Future > calls to fsync will then return EIO when this flag is set. We clear the flag > when the vnode is released.
Sounds reasonable. OK bluhm@ > Index: kern/vfs_bio.c > =================================================================== > RCS file: /home/cvs/src/sys/kern/vfs_bio.c,v > retrieving revision 1.187 > diff -u -p -r1.187 vfs_bio.c > --- kern/vfs_bio.c 21 Nov 2018 16:14:43 -0000 1.187 > +++ kern/vfs_bio.c 31 Jan 2019 21:19:36 -0000 > @@ -867,6 +867,11 @@ brelse(struct buf *bp) > /* If it's not cacheable, or an error, mark it invalid. */ > if (ISSET(bp->b_flags, (B_NOCACHE|B_ERROR))) > SET(bp->b_flags, B_INVAL); > + /* If it's a write error, also mark the vnode as damaged. */ > + if (ISSET(bp->b_flags, B_ERROR) && !ISSET(bp->b_flags, B_READ)) { > + if (bp->b_vp && bp->b_vp->v_type == VREG) > + SET(bp->b_vp->v_bioflag, VBIOERROR); > + } > > if (ISSET(bp->b_flags, B_INVAL)) { > /* > Index: kern/vfs_subr.c > =================================================================== > RCS file: /home/cvs/src/sys/kern/vfs_subr.c,v > retrieving revision 1.285 > diff -u -p -r1.285 vfs_subr.c > --- kern/vfs_subr.c 21 Jan 2019 18:09:21 -0000 1.285 > +++ kern/vfs_subr.c 31 Jan 2019 21:09:22 -0000 > @@ -712,6 +712,7 @@ vputonfreelist(struct vnode *vp) > #endif > > vp->v_bioflag |= VBIOONFREELIST; > + vp->v_bioflag &= ~VBIOERROR; > > if (vp->v_holdcnt > 0) > lst = &vnode_hold_list; > Index: kern/vfs_vops.c > =================================================================== > RCS file: /home/cvs/src/sys/kern/vfs_vops.c,v > retrieving revision 1.19 > diff -u -p -r1.19 vfs_vops.c > --- kern/vfs_vops.c 21 Jun 2018 14:17:23 -0000 1.19 > +++ kern/vfs_vops.c 31 Jan 2019 21:04:43 -0000 > @@ -336,7 +336,7 @@ int > VOP_FSYNC(struct vnode *vp, struct ucred *cred, int waitfor, > struct proc *p) > { > - int r; > + int r, s; > struct vop_fsync_args a; > a.a_vp = vp; > a.a_cred = cred; > @@ -351,6 +351,10 @@ VOP_FSYNC(struct vnode *vp, struct ucred > vp->v_inflight++; > r = (vp->v_op->vop_fsync)(&a); > vp->v_inflight--; > + s = splbio(); > + if (r == 0 && vp->v_bioflag & VBIOERROR) > + r = EIO; > + splx(s); > return r; > } > > Index: sys/vnode.h > =================================================================== > RCS file: /home/cvs/src/sys/sys/vnode.h,v > retrieving revision 1.149 > diff -u -p -r1.149 vnode.h > --- sys/vnode.h 23 Dec 2018 10:46:51 -0000 1.149 > +++ sys/vnode.h 31 Jan 2019 20:52:37 -0000 > @@ -149,6 +149,7 @@ struct vnode { > #define VBIOWAIT 0x0001 /* waiting for output to complete */ > #define VBIOONSYNCLIST 0x0002 /* Vnode is on syncer worklist */ > #define VBIOONFREELIST 0x0004 /* Vnode is on a free list */ > +#define VBIOERROR 0x0008 /* A write failed */ > > /* > * Vnode attributes. A field value of VNOVAL represents a field whose value