Bugfix/fix uio partial copies

In zfs_write(), the loop continues to the next iteration without
accounting for partial copies occurring in uiomove_iov when 
copy_from_user/__copy_from_user_inatomic return a non-zero status.
This results in "zfs: accessing past end of object..." in the 
kernel log, and the write failing.

Account for partial copies and update uio struct before returning
EFAULT, leave a comment explaining the reason why this is done.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: ilbsmart <wgqimut@gmail.com>
Signed-off-by: Fabio Scaccabarozzi <fsvm88@gmail.com>
Closes #8673 
Closes #10148
This commit is contained in:
Fabio Scaccabarozzi
2020-04-01 18:48:54 +02:00
committed by GitHub
parent 0929c4de39
commit c9e3efdb3a
2 changed files with 26 additions and 8 deletions
+9
View File
@@ -829,6 +829,15 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
uio->uio_fault_disable = B_FALSE;
if (error == EFAULT) {
dmu_tx_commit(tx);
/*
* Account for partial writes before
* continuing the loop.
* Update needs to occur before the next
* uio_prefaultpages, or prefaultpages may
* error, and we may break the loop early.
*/
if (tx_bytes != uio->uio_resid)
n -= tx_bytes - uio->uio_resid;
if (uio_prefaultpages(MIN(n, max_blksz), uio)) {
break;
}