Skip to content

Commit fdbd1a2

Browse files
bcodding-rhTrond Myklebust
authored andcommitted
nfs: Fix a missed page unlock after pg_doio()
We must check pg_error and call error_cleanup after any call to pg_doio. Currently, we are skipping the unlock of a page if we encounter an error in nfs_pageio_complete() before handing off the work to the RPC layer. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent e732f44 commit fdbd1a2

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

fs/nfs/pagelist.c

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,20 @@ static int nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc,
11101110
return ret;
11111111
}
11121112

1113+
static void nfs_pageio_error_cleanup(struct nfs_pageio_descriptor *desc)
1114+
{
1115+
u32 midx;
1116+
struct nfs_pgio_mirror *mirror;
1117+
1118+
if (!desc->pg_error)
1119+
return;
1120+
1121+
for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1122+
mirror = &desc->pg_mirrors[midx];
1123+
desc->pg_completion_ops->error_cleanup(&mirror->pg_list);
1124+
}
1125+
}
1126+
11131127
int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
11141128
struct nfs_page *req)
11151129
{
@@ -1160,25 +1174,11 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
11601174
return 1;
11611175

11621176
out_failed:
1163-
/*
1164-
* We might have failed before sending any reqs over wire.
1165-
* Clean up rest of the reqs in mirror pg_list.
1166-
*/
1167-
if (desc->pg_error) {
1168-
struct nfs_pgio_mirror *mirror;
1169-
void (*func)(struct list_head *);
1170-
1171-
/* remember fatal errors */
1172-
if (nfs_error_is_fatal(desc->pg_error))
1173-
nfs_context_set_write_error(req->wb_context,
1174-
desc->pg_error);
1175-
1176-
func = desc->pg_completion_ops->error_cleanup;
1177-
for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1178-
mirror = &desc->pg_mirrors[midx];
1179-
func(&mirror->pg_list);
1180-
}
1181-
}
1177+
/* remember fatal errors */
1178+
if (nfs_error_is_fatal(desc->pg_error))
1179+
nfs_context_set_write_error(req->wb_context,
1180+
desc->pg_error);
1181+
nfs_pageio_error_cleanup(desc);
11821182
return 0;
11831183
}
11841184

@@ -1250,6 +1250,8 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
12501250
for (midx = 0; midx < desc->pg_mirror_count; midx++)
12511251
nfs_pageio_complete_mirror(desc, midx);
12521252

1253+
if (desc->pg_error < 0)
1254+
nfs_pageio_error_cleanup(desc);
12531255
if (desc->pg_ops->pg_cleanup)
12541256
desc->pg_ops->pg_cleanup(desc);
12551257
nfs_pageio_cleanup_mirroring(desc);

0 commit comments

Comments
 (0)