mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
NFS/localio: Stop further I/O upon hitting an error
If the call into the filesystem results in an I/O error, then the next
chunk of data won't be contiguous with the end of the last successful
chunk. So break out of the I/O loop and report the results.
Currently the localio code will do this for a short read/write, but not
for an error.
Fixes: 6a218b9c31 ("nfs/localio: do not issue misaligned DIO out-of-order")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Reviewed-by: Mike Snitzer <snitzer@kernel.org>
This commit is contained in:
parent
df56ddd057
commit
001945a777
|
|
@ -618,7 +618,6 @@ static void nfs_local_call_read(struct work_struct *work)
|
|||
struct nfs_local_kiocb *iocb =
|
||||
container_of(work, struct nfs_local_kiocb, work);
|
||||
struct file *filp = iocb->kiocb.ki_filp;
|
||||
bool force_done = false;
|
||||
ssize_t status;
|
||||
int n_iters;
|
||||
|
||||
|
|
@ -637,13 +636,13 @@ static void nfs_local_call_read(struct work_struct *work)
|
|||
scoped_with_creds(filp->f_cred)
|
||||
status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]);
|
||||
|
||||
if (status != -EIOCBQUEUED) {
|
||||
if (unlikely(status >= 0 && status < iocb->iters[i].count))
|
||||
force_done = true; /* Partial read */
|
||||
if (nfs_local_pgio_done(iocb, status, force_done)) {
|
||||
nfs_local_read_iocb_done(iocb);
|
||||
break;
|
||||
}
|
||||
if (status == -EIOCBQUEUED)
|
||||
continue;
|
||||
/* Break on completion, errors, or short reads */
|
||||
if (nfs_local_pgio_done(iocb, status, false) || status < 0 ||
|
||||
(size_t)status < iov_iter_count(&iocb->iters[i])) {
|
||||
nfs_local_read_iocb_done(iocb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -821,7 +820,6 @@ static void nfs_local_call_write(struct work_struct *work)
|
|||
container_of(work, struct nfs_local_kiocb, work);
|
||||
struct file *filp = iocb->kiocb.ki_filp;
|
||||
unsigned long old_flags = current->flags;
|
||||
bool force_done = false;
|
||||
ssize_t status;
|
||||
int n_iters;
|
||||
|
||||
|
|
@ -843,13 +841,13 @@ static void nfs_local_call_write(struct work_struct *work)
|
|||
scoped_with_creds(filp->f_cred)
|
||||
status = filp->f_op->write_iter(&iocb->kiocb, &iocb->iters[i]);
|
||||
|
||||
if (status != -EIOCBQUEUED) {
|
||||
if (unlikely(status >= 0 && status < iocb->iters[i].count))
|
||||
force_done = true; /* Partial write */
|
||||
if (nfs_local_pgio_done(iocb, status, force_done)) {
|
||||
nfs_local_write_iocb_done(iocb);
|
||||
break;
|
||||
}
|
||||
if (status == -EIOCBQUEUED)
|
||||
continue;
|
||||
/* Break on completion, errors, or short writes */
|
||||
if (nfs_local_pgio_done(iocb, status, false) || status < 0 ||
|
||||
(size_t)status < iov_iter_count(&iocb->iters[i])) {
|
||||
nfs_local_write_iocb_done(iocb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
file_end_write(filp);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user