From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
torvalds@linux-foundation.org, stable@vger.kernel.org
Cc: lwn@lwn.net, jslaby@suse.cz,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: Linux 6.1.58
Date: Sun, 15 Oct 2023 18:43:19 +0200 [thread overview]
Message-ID: <2023101519-stool-overtime-f1f4@gregkh> (raw)
In-Reply-To: <2023101518-subscript-entity-be71@gregkh>
diff --git a/Makefile b/Makefile
index b435b56594f0..ce1eec0b5010 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 1
-SUBLEVEL = 57
+SUBLEVEL = 58
EXTRAVERSION =
NAME = Curry Ramen
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 5a976fa343df..3bb530d4bb5c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -93,10 +93,12 @@ nfs_direct_handle_truncated(struct nfs_direct_req *dreq,
dreq->max_count = dreq_len;
if (dreq->count > dreq_len)
dreq->count = dreq_len;
- }
- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && !dreq->error)
- dreq->error = hdr->error;
+ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
+ dreq->error = hdr->error;
+ else /* Clear outstanding error if this is EOF */
+ dreq->error = 0;
+ }
}
static void
@@ -118,18 +120,6 @@ nfs_direct_count_bytes(struct nfs_direct_req *dreq,
dreq->count = dreq_len;
}
-static void nfs_direct_truncate_request(struct nfs_direct_req *dreq,
- struct nfs_page *req)
-{
- loff_t offs = req_offset(req);
- size_t req_start = (size_t)(offs - dreq->io_start);
-
- if (req_start < dreq->max_count)
- dreq->max_count = req_start;
- if (req_start < dreq->count)
- dreq->count = req_start;
-}
-
/**
* nfs_swap_rw - NFS address space operation for swap I/O
* @iocb: target I/O control block
@@ -500,9 +490,7 @@ static void nfs_direct_add_page_head(struct list_head *list,
kref_get(&head->wb_kref);
}
-static void nfs_direct_join_group(struct list_head *list,
- struct nfs_commit_info *cinfo,
- struct inode *inode)
+static void nfs_direct_join_group(struct list_head *list, struct inode *inode)
{
struct nfs_page *req, *subreq;
@@ -524,7 +512,7 @@ static void nfs_direct_join_group(struct list_head *list,
nfs_release_request(subreq);
}
} while ((subreq = subreq->wb_this_page) != req);
- nfs_join_page_group(req, cinfo, inode);
+ nfs_join_page_group(req, inode);
}
}
@@ -542,15 +530,20 @@ 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);
- nfs_direct_join_group(&reqs, &cinfo, dreq->inode);
+ nfs_direct_join_group(&reqs, dreq->inode);
+ dreq->count = 0;
+ dreq->max_count = 0;
+ list_for_each_entry(req, &reqs, wb_list)
+ dreq->max_count += req->wb_bytes;
nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo);
get_dreq(dreq);
@@ -558,40 +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)) {
- spin_lock(&dreq->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;
+ nfs_list_move_request(req, &failed);
+ spin_lock(&cinfo.inode->i_lock);
+ dreq->flags = 0;
+ if (desc.pg_error < 0)
dreq->error = desc.pg_error;
- } else
- dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
- spin_unlock(&dreq->lock);
- break;
+ else
+ dreq->error = -EIO;
+ spin_unlock(&cinfo.inode->i_lock);
}
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 {
- spin_lock(&dreq->lock);
- nfs_direct_truncate_request(dreq, req);
- spin_unlock(&dreq->lock);
- nfs_release_request(req);
- }
}
if (put_dreq(dreq))
@@ -611,6 +591,8 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
if (status < 0) {
/* Errors in commit are fatal */
dreq->error = status;
+ dreq->max_count = 0;
+ dreq->count = 0;
dreq->flags = NFS_ODIRECT_DONE;
} else {
status = dreq->error;
@@ -621,12 +603,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
while (!list_empty(&data->pages)) {
req = nfs_list_entry(data->pages.next);
nfs_list_remove_request(req);
- if (status < 0) {
- spin_lock(&dreq->lock);
- nfs_direct_truncate_request(dreq, req);
- spin_unlock(&dreq->lock);
- nfs_release_request(req);
- } else if (!nfs_write_match_verf(verf, req)) {
+ if (status >= 0 && !nfs_write_match_verf(verf, req)) {
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
/*
* Despite the reboot, the write was successful,
@@ -634,7 +611,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
*/
req->wb_nio = 0;
nfs_mark_request_commit(req, NULL, &cinfo, 0);
- } else
+ } else /* Error or match */
nfs_release_request(req);
nfs_unlock_and_release_request(req);
}
@@ -687,7 +664,6 @@ static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq)
while (!list_empty(&reqs)) {
req = nfs_list_entry(reqs.next);
nfs_list_remove_request(req);
- nfs_direct_truncate_request(dreq, req);
nfs_release_request(req);
nfs_unlock_and_release_request(req);
}
@@ -737,8 +713,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
}
nfs_direct_count_bytes(dreq, hdr);
- if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags) &&
- !test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
+ if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags)) {
if (!dreq->flags)
dreq->flags = NFS_ODIRECT_DO_COMMIT;
flags = dreq->flags;
@@ -782,23 +757,18 @@ static void nfs_write_sync_pgio_error(struct list_head *head, int error)
static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr)
{
struct nfs_direct_req *dreq = hdr->dreq;
- struct nfs_page *req;
- struct nfs_commit_info cinfo;
trace_nfs_direct_write_reschedule_io(dreq);
- nfs_init_cinfo_from_dreq(&cinfo, dreq);
spin_lock(&dreq->lock);
- if (dreq->error == 0)
+ if (dreq->error == 0) {
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
- set_bit(NFS_IOHDR_REDO, &hdr->flags);
- spin_unlock(&dreq->lock);
- while (!list_empty(&hdr->pages)) {
- req = nfs_list_entry(hdr->pages.next);
- nfs_list_remove_request(req);
- nfs_unlock_request(req);
- nfs_mark_request_commit(req, NULL, &cinfo, 0);
+ /* fake unstable write to let common nfs resend pages */
+ hdr->verf.committed = NFS_UNSTABLE;
+ hdr->good_bytes = hdr->args.offset + hdr->args.count -
+ hdr->io_start;
}
+ spin_unlock(&dreq->lock);
}
static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = {
@@ -826,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);
@@ -871,39 +839,19 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
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) {
+ if (!nfs_pageio_add_request(&desc, req)) {
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(&dreq->lock);
- dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
- spin_unlock(&dreq->lock);
- nfs_unlock_request(req);
- nfs_mark_request_commit(req, NULL, &cinfo, 0);
- desc.pg_error = 0;
- defer = true;
+ pgbase = 0;
+ bytes -= req_len;
+ requested_bytes += req_len;
+ pos += req_len;
+ dreq->bytes_left -= req_len;
}
nfs_direct_release_pages(pagevec, npages);
kvfree(pagevec);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0a8aed0ac994..f41d24b54fd1 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -58,8 +58,7 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
static const struct nfs_rw_ops nfs_rw_write_ops;
static void nfs_inode_remove_request(struct nfs_page *req);
-static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
- struct nfs_page *req);
+static void nfs_clear_request_commit(struct nfs_page *req);
static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
struct inode *inode);
static struct nfs_page *
@@ -503,8 +502,8 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list,
* the (former) group. All subrequests are removed from any write or commit
* lists, unlinked from the group and destroyed.
*/
-void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo,
- struct inode *inode)
+void
+nfs_join_page_group(struct nfs_page *head, struct inode *inode)
{
struct nfs_page *subreq;
struct nfs_page *destroy_list = NULL;
@@ -534,7 +533,7 @@ void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo,
* Commit list removal accounting is done after locks are dropped */
subreq = head;
do {
- nfs_clear_request_commit(cinfo, subreq);
+ nfs_clear_request_commit(subreq);
subreq = subreq->wb_this_page;
} while (subreq != head);
@@ -568,10 +567,8 @@ nfs_lock_and_join_requests(struct page *page)
{
struct inode *inode = page_file_mapping(page)->host;
struct nfs_page *head;
- struct nfs_commit_info cinfo;
int ret;
- nfs_init_cinfo_from_inode(&cinfo, inode);
/*
* A reference is taken only on the head request which acts as a
* reference to the whole page group - the group will not be destroyed
@@ -588,7 +585,7 @@ nfs_lock_and_join_requests(struct page *page)
return ERR_PTR(ret);
}
- nfs_join_page_group(head, &cinfo, inode);
+ nfs_join_page_group(head, inode);
return head;
}
@@ -959,16 +956,18 @@ nfs_clear_page_commit(struct page *page)
}
/* Called holding the request lock on @req */
-static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
- struct nfs_page *req)
+static void
+nfs_clear_request_commit(struct nfs_page *req)
{
if (test_bit(PG_CLEAN, &req->wb_flags)) {
struct nfs_open_context *ctx = nfs_req_openctx(req);
struct inode *inode = d_inode(ctx->dentry);
+ struct nfs_commit_info cinfo;
+ nfs_init_cinfo_from_inode(&cinfo, inode);
mutex_lock(&NFS_I(inode)->commit_mutex);
- if (!pnfs_clear_request_commit(req, cinfo)) {
- nfs_request_remove_commit_list(req, cinfo);
+ if (!pnfs_clear_request_commit(req, &cinfo)) {
+ nfs_request_remove_commit_list(req, &cinfo);
}
mutex_unlock(&NFS_I(inode)->commit_mutex);
nfs_clear_page_commit(req->wb_page);
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index e39a8cf8b179..ba7e2e4b0926 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -145,9 +145,7 @@ extern void nfs_unlock_request(struct nfs_page *req);
extern void nfs_unlock_and_release_request(struct nfs_page *);
extern struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
extern int nfs_page_group_lock_subrequests(struct nfs_page *head);
-extern void nfs_join_page_group(struct nfs_page *head,
- struct nfs_commit_info *cinfo,
- struct inode *inode);
+extern void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
extern int nfs_page_group_lock(struct nfs_page *);
extern void nfs_page_group_unlock(struct nfs_page *);
extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
diff --git a/lib/test_meminit.c b/lib/test_meminit.c
index 0ae35223d773..85d8dd8e01dc 100644
--- a/lib/test_meminit.c
+++ b/lib/test_meminit.c
@@ -93,7 +93,7 @@ static int __init test_pages(int *total_failures)
int failures = 0, num_tests = 0;
int i;
- for (i = 0; i <= MAX_ORDER; i++)
+ for (i = 0; i < MAX_ORDER; i++)
num_tests += do_alloc_pages_order(i, &failures);
REPORT_FAILURES_IN_FN();
next prev parent reply other threads:[~2023-10-15 16:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-15 16:43 Linux 6.1.58 Greg Kroah-Hartman
2023-10-15 16:43 ` Greg Kroah-Hartman [this message]
2023-10-20 7:22 ` NeilBrown
2023-10-20 14:22 ` Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2023101519-stool-overtime-f1f4@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=akpm@linux-foundation.org \
--cc=jslaby@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=lwn@lwn.net \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.