[Midnightbsd-cvs] src [7931] trunk/sys/fs/nfsclient/nfs_clbio.c: improve handling of uiomove(9) errors for the NFS client.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Wed Sep 14 17:11:09 EDT 2016
Revision: 7931
http://svnweb.midnightbsd.org/src/?rev=7931
Author: laffer1
Date: 2016-09-14 17:11:09 -0400 (Wed, 14 Sep 2016)
Log Message:
-----------
improve handling of uiomove(9) errors for the NFS client.
Modified Paths:
--------------
trunk/sys/fs/nfsclient/nfs_clbio.c
Modified: trunk/sys/fs/nfsclient/nfs_clbio.c
===================================================================
--- trunk/sys/fs/nfsclient/nfs_clbio.c 2016-09-14 21:09:43 UTC (rev 7930)
+++ trunk/sys/fs/nfsclient/nfs_clbio.c 2016-09-14 21:11:09 UTC (rev 7931)
@@ -873,8 +873,9 @@
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
daddr_t lbn;
int bcount;
- int n, on, error = 0;
- off_t tmp_off;
+ int bp_cached, n, on, error = 0;
+ size_t orig_resid, local_resid;
+ off_t orig_size, tmp_off;
KASSERT(uio->uio_rw == UIO_WRITE, ("ncl_write mode"));
KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
@@ -926,6 +927,11 @@
mtx_unlock(&np->n_mtx);
}
+ orig_resid = uio->uio_resid;
+ mtx_lock(&np->n_mtx);
+ orig_size = np->n_size;
+ mtx_unlock(&np->n_mtx);
+
/*
* If IO_APPEND then load uio_offset. We restart here if we cannot
* get the append lock.
@@ -1103,7 +1109,10 @@
* normally.
*/
+ bp_cached = 1;
if (on == 0 && n == bcount) {
+ if ((bp->b_flags & B_CACHE) == 0)
+ bp_cached = 0;
bp->b_flags |= B_CACHE;
bp->b_flags &= ~B_INVAL;
bp->b_ioflags &= ~BIO_ERROR;
@@ -1169,8 +1178,24 @@
goto again;
}
+ local_resid = uio->uio_resid;
error = uiomove((char *)bp->b_data + on, n, uio);
+ if (error != 0 && !bp_cached) {
+ /*
+ * This block has no other content then what
+ * possibly was written by the faulty uiomove.
+ * Release it, forgetting the data pages, to
+ * prevent the leak of uninitialized data to
+ * usermode.
+ */
+ bp->b_ioflags |= BIO_ERROR;
+ brelse(bp);
+ uio->uio_offset -= local_resid - uio->uio_resid;
+ uio->uio_resid = local_resid;
+ break;
+ }
+
/*
* Since this block is being modified, it must be written
* again and not just committed. Since write clustering does
@@ -1179,17 +1204,18 @@
*/
bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
- if (error) {
- bp->b_ioflags |= BIO_ERROR;
- brelse(bp);
- break;
- }
+ /*
+ * Get the partial update on the progress made from
+ * uiomove, if an error occured.
+ */
+ if (error != 0)
+ n = local_resid - uio->uio_resid;
/*
* Only update dirtyoff/dirtyend if not a degenerate
* condition.
*/
- if (n) {
+ if (n > 0) {
if (bp->b_dirtyend > 0) {
bp->b_dirtyoff = min(on, bp->b_dirtyoff);
bp->b_dirtyend = max((on + n), bp->b_dirtyend);
@@ -1218,8 +1244,22 @@
} else {
bdwrite(bp);
}
+
+ if (error != 0)
+ break;
} while (uio->uio_resid > 0 && n > 0);
+ if (error != 0) {
+ if (ioflag & IO_UNIT) {
+ VATTR_NULL(&vattr);
+ vattr.va_size = orig_size;
+ /* IO_SYNC is handled implicitely */
+ (void)VOP_SETATTR(vp, &vattr, cred);
+ uio->uio_offset -= orig_resid - uio->uio_resid;
+ uio->uio_resid = orig_resid;
+ }
+ }
+
return (error);
}
More information about the Midnightbsd-cvs
mailing list