summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsclient/nfs_clbio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsclient/nfs_clbio.c')
-rw-r--r--sys/fs/nfsclient/nfs_clbio.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index d0dd2cc..2401c88 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -336,7 +336,7 @@ ncl_putpages(struct vop_putpages_args *ap)
else
iomode = NFSWRITE_FILESYNC;
- error = ncl_writerpc(vp, &uio, cred, &iomode, &must_commit);
+ error = ncl_writerpc(vp, &uio, cred, &iomode, &must_commit, 0);
pmap_qremove(kva, npages);
relpbuf(bp, &ncl_pbuf_freecnt);
@@ -554,7 +554,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
brelse(bp);
return (error);
@@ -583,7 +583,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
bp->b_ioflags |= BIO_ERROR;
brelse(bp);
@@ -609,7 +609,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
brelse(bp);
}
@@ -638,7 +638,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
/*
* no error + B_INVAL == directory EOF,
* use the block.
@@ -771,7 +771,7 @@ do_sync:
uio.uio_td = td;
iomode = NFSWRITE_FILESYNC;
error = ncl_writerpc(vp, &uio, cred, &iomode,
- &must_commit);
+ &must_commit, 0);
KASSERT((must_commit == 0),
("ncl_directio_write: Did not commit write"));
if (error)
@@ -1122,7 +1122,7 @@ again:
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_iocmd = BIO_READ;
vfs_busy_pages(bp, 0);
- error = ncl_doio(vp, bp, cred, td);
+ error = ncl_doio(vp, bp, cred, td, 0);
if (error) {
brelse(bp);
break;
@@ -1523,7 +1523,7 @@ ncl_doio_directwrite(struct buf *bp)
iomode = NFSWRITE_FILESYNC;
uiop->uio_td = NULL; /* NULL since we're in nfsiod */
- ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit);
+ ncl_writerpc(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit, 0);
KASSERT((must_commit == 0), ("ncl_doio_directwrite: Did not commit write"));
free(iov_base, M_NFSDIRECTIO);
free(uiop->uio_iov, M_NFSDIRECTIO);
@@ -1550,7 +1550,8 @@ ncl_doio_directwrite(struct buf *bp)
* synchronously or from an nfsiod.
*/
int
-ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
+ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td,
+ int called_from_strategy)
{
struct uio *uiop;
struct nfsnode *np;
@@ -1695,7 +1696,8 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
else
iomode = NFSWRITE_FILESYNC;
- error = ncl_writerpc(vp, uiop, cr, &iomode, &must_commit);
+ error = ncl_writerpc(vp, uiop, cr, &iomode, &must_commit,
+ called_from_strategy);
/*
* When setting B_NEEDCOMMIT also set B_CLUSTEROK to try
@@ -1732,6 +1734,12 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
* the block is reused. This is indicated by setting
* the B_DELWRI and B_NEEDCOMMIT flags.
*
+ * EIO is returned by ncl_writerpc() to indicate a recoverable
+ * write error and is handled as above, except that
+ * B_EINTR isn't set. One cause of this is a stale stateid
+ * error for the RPC that indicates recovery is required,
+ * when called with called_from_strategy != 0.
+ *
* If the buffer is marked B_PAGING, it does not reside on
* the vp's paging queues so we cannot call bdirty(). The
* bp in this case is not an NFS cache block so we should
@@ -1760,7 +1768,8 @@ ncl_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
bdirty(bp);
bp->b_flags &= ~B_DONE;
}
- if (error && (bp->b_flags & B_ASYNC) == 0)
+ if ((error == EINTR || error == ETIMEDOUT) &&
+ (bp->b_flags & B_ASYNC) == 0)
bp->b_flags |= B_EINTR;
splx(s);
} else {
OpenPOWER on IntegriCloud