From ff74bdc83847f9e15d7573ac1f4ce1c1b56c2470 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 Oct 2023 19:41:42 +0200 Subject: [PATCH] Revert "NFS: Fix error handling for O_DIRECT write scheduling" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit f16fd0b11f0f4d41846b5102b1656ea1fc9ac7a0 which is commit 954998b60caa8f2a3bf3abe490de6f08d283687a upstream. There are reported NFS problems in the 6.1.56 release, so revert a set of NFS patches to hopefully resolve the issue. Reported-by: poester Link: https://lore.kernel.org/r/20231012165439.137237-2-kernel@linuxace.com Reported-by: Daniel Díaz Link: https://lore.kernel.org/r/2023100755-livestock-barcode-fe41@gregkh Cc: Trond Myklebust Cc: Anna Schumaker Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfs/direct.c | 66 ++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 48 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index d71762f32b6c..3bb530d4bb5c 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -530,9 +530,10 @@ nfs_direct_write_scan_commit_list(struct inode *inode, static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) { struct nfs_pageio_descriptor desc; - struct nfs_page *req; + struct nfs_page *req, *tmp; LIST_HEAD(reqs); struct nfs_commit_info cinfo; + LIST_HEAD(failed); nfs_init_cinfo_from_dreq(&cinfo, dreq); nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); @@ -550,36 +551,27 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) &nfs_direct_write_completion_ops); desc.pg_dreq = dreq; - while (!list_empty(&reqs)) { - req = nfs_list_entry(reqs.next); + list_for_each_entry_safe(req, tmp, &reqs, wb_list) { /* Bump the transmission count */ req->wb_nio++; if (!nfs_pageio_add_request(&desc, req)) { + nfs_list_move_request(req, &failed); spin_lock(&cinfo.inode->i_lock); - if (dreq->error < 0) { - desc.pg_error = dreq->error; - } else if (desc.pg_error != -EAGAIN) { - dreq->flags = 0; - if (!desc.pg_error) - desc.pg_error = -EIO; + dreq->flags = 0; + if (desc.pg_error < 0) dreq->error = desc.pg_error; - } else - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + else + dreq->error = -EIO; spin_unlock(&cinfo.inode->i_lock); - break; } nfs_release_request(req); } nfs_pageio_complete(&desc); - while (!list_empty(&reqs)) { - req = nfs_list_entry(reqs.next); + while (!list_empty(&failed)) { + req = nfs_list_entry(failed.next); nfs_list_remove_request(req); nfs_unlock_and_release_request(req); - if (desc.pg_error == -EAGAIN) - nfs_mark_request_commit(req, NULL, &cinfo, 0); - else - nfs_release_request(req); } if (put_dreq(dreq)) @@ -804,11 +796,9 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, { struct nfs_pageio_descriptor desc; struct inode *inode = dreq->inode; - struct nfs_commit_info cinfo; ssize_t result = 0; size_t requested_bytes = 0; size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); - bool defer = false; trace_nfs_direct_write_schedule_iovec(dreq); @@ -849,39 +839,19 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, break; } + nfs_lock_request(req); + req->wb_index = pos >> PAGE_SHIFT; + req->wb_offset = pos & ~PAGE_MASK; + if (!nfs_pageio_add_request(&desc, req)) { + result = desc.pg_error; + nfs_unlock_and_release_request(req); + break; + } pgbase = 0; bytes -= req_len; requested_bytes += req_len; pos += req_len; dreq->bytes_left -= req_len; - - if (defer) { - nfs_mark_request_commit(req, NULL, &cinfo, 0); - continue; - } - - nfs_lock_request(req); - req->wb_index = pos >> PAGE_SHIFT; - req->wb_offset = pos & ~PAGE_MASK; - if (nfs_pageio_add_request(&desc, req)) - continue; - - /* Exit on hard errors */ - if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) { - result = desc.pg_error; - nfs_unlock_and_release_request(req); - break; - } - - /* If the error is soft, defer remaining requests */ - nfs_init_cinfo_from_dreq(&cinfo, dreq); - spin_lock(&cinfo.inode->i_lock); - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; - spin_unlock(&cinfo.inode->i_lock); - nfs_unlock_request(req); - nfs_mark_request_commit(req, NULL, &cinfo, 0); - desc.pg_error = 0; - defer = true; } nfs_direct_release_pages(pagevec, npages); kvfree(pagevec);