From: Jeff Layton jlayton@kernel.org
mainline inclusion from mainline-v6.0-rc1 commit 55051c0ced7d322a169f8603d306ee6ec079f8ae category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IARK13
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
When the client gets back a short DIO write, it will then attempt to issue another write to finish the DIO request. If that write then fails (as is often the case in an -ENOSPC situation), then we still may need to issue a COMMIT if the earlier short write was unstable. If that COMMIT then succeeds, then we don't want the client to reschedule the write requests, and to instead just return a short write. Otherwise, we can end up looping over the same DIO write forever.
Always consult dreq->error after a successful RPC, even when the flag state is not NFS_ODIRECT_DONE.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2028370 Reported-by: Boyang Xue bxue@redhat.com Signed-off-by: Jeff Layton jlayton@kernel.org Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Li Lingfeng lilingfeng3@huawei.com --- fs/nfs/direct.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 499519f0f6ec..5b8ab542ee84 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -629,8 +629,9 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) dreq->max_count = 0; dreq->count = 0; dreq->flags = NFS_ODIRECT_DONE; - } else if (dreq->flags == NFS_ODIRECT_DONE) + } else { status = dreq->error; + }
nfs_init_cinfo_from_dreq(&cinfo, dreq);