aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Moeller <[email protected]>2020-11-14 13:16:26 -0500
committerBrian Behlendorf <[email protected]>2020-12-23 14:35:00 -0800
commitaf5626ac27bc34aa4377da3b7a02e96cdbadd904 (patch)
treec0a079b6d032bef0d5e08f363378f86dcdf9507f
parentcc1f85be8bee7d2f06c7233d26c77649c8a68540 (diff)
Return EFAULT at the end of zfs_write() when set
FreeBSD's VFS expects EFAULT from zfs_write() if we didn't complete the full write so it can retry the operation. Add some missing SET_ERRORs in zfs_write(). Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ryan Moeller <[email protected]> Closes #11193
-rw-r--r--module/zfs/zfs_vnops.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index a3a3482c3..752e702fc 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -320,7 +320,7 @@ zfs_write(znode_t *zp, uio_t *uio, int ioflag, cred_t *cr)
if (zn_rlimit_fsize(zp, uio, uio->uio_td)) {
zfs_rangelock_exit(lr);
ZFS_EXIT(zfsvfs);
- return (EFBIG);
+ return (SET_ERROR(EFBIG));
}
const rlim64_t limit = MAXOFFSET_T;
@@ -560,7 +560,7 @@ zfs_write(znode_t *zp, uio_t *uio, int ioflag, cred_t *cr)
if (n > 0) {
if (uio_prefaultpages(MIN(n, max_blksz), uio)) {
- error = EFAULT;
+ error = SET_ERROR(EFAULT);
break;
}
}
@@ -570,10 +570,12 @@ zfs_write(znode_t *zp, uio_t *uio, int ioflag, cred_t *cr)
zfs_rangelock_exit(lr);
/*
- * If we're in replay mode, or we made no progress, return error.
- * Otherwise, it's at least a partial write, so it's successful.
+ * If we're in replay mode, or we made no progress, or the
+ * uio data is inaccessible return an error. Otherwise, it's
+ * at least a partial write, so it's successful.
*/
- if (zfsvfs->z_replay || uio->uio_resid == start_resid) {
+ if (zfsvfs->z_replay || uio->uio_resid == start_resid ||
+ error == EFAULT) {
ZFS_EXIT(zfsvfs);
return (error);
}