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

Reply via email to