hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/nfs/read.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * linux/fs/nfs/read.c
34 *
....@@ -90,19 +91,25 @@
9091 }
9192 EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
9293
93
-static void nfs_readpage_release(struct nfs_page *req)
94
+static void nfs_readpage_release(struct nfs_page *req, int error)
9495 {
95
- struct inode *inode = d_inode(req->wb_context->dentry);
96
+ struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);
97
+ struct page *page = req->wb_page;
9698
9799 dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id,
98100 (unsigned long long)NFS_FILEID(inode), req->wb_bytes,
99101 (long long)req_offset(req));
100102
103
+ if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT)
104
+ SetPageError(page);
101105 if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) {
102
- if (PageUptodate(req->wb_page))
103
- nfs_readpage_to_fscache(inode, req->wb_page, 0);
106
+ struct address_space *mapping = page_file_mapping(page);
104107
105
- unlock_page(req->wb_page);
108
+ if (PageUptodate(page))
109
+ nfs_readpage_to_fscache(inode, page, 0);
110
+ else if (!PageError(page) && !PagePrivate(page))
111
+ generic_error_remove_page(mapping, page);
112
+ unlock_page(page);
106113 }
107114 nfs_release_request(req);
108115 }
....@@ -118,7 +125,7 @@
118125 len = nfs_page_length(page);
119126 if (len == 0)
120127 return nfs_return_empty_page(page);
121
- new = nfs_create_request(ctx, page, NULL, 0, len);
128
+ new = nfs_create_request(ctx, page, 0, len);
122129 if (IS_ERR(new)) {
123130 unlock_page(page);
124131 return PTR_ERR(new);
....@@ -130,7 +137,7 @@
130137 &nfs_async_read_completion_ops);
131138 if (!nfs_pageio_add_request(&pgio, new)) {
132139 nfs_list_remove_request(new);
133
- nfs_readpage_release(new);
140
+ nfs_readpage_release(new, pgio.pg_error);
134141 }
135142 nfs_pageio_complete(&pgio);
136143
....@@ -152,6 +159,7 @@
152159 static void nfs_read_completion(struct nfs_pgio_header *hdr)
153160 {
154161 unsigned long bytes = 0;
162
+ int error;
155163
156164 if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
157165 goto out;
....@@ -178,14 +186,19 @@
178186 zero_user_segment(page, start, end);
179187 }
180188 }
189
+ error = 0;
181190 bytes += req->wb_bytes;
182191 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
183192 if (bytes <= hdr->good_bytes)
184193 nfs_page_group_set_uptodate(req);
194
+ else {
195
+ error = hdr->error;
196
+ xchg(&nfs_req_openctx(req)->error, error);
197
+ }
185198 } else
186199 nfs_page_group_set_uptodate(req);
187200 nfs_list_remove_request(req);
188
- nfs_readpage_release(req);
201
+ nfs_readpage_release(req, error);
189202 }
190203 out:
191204 hdr->release(hdr);
....@@ -201,7 +214,7 @@
201214
202215 task_setup_data->flags |= swap_flags;
203216 rpc_ops->read_setup(hdr, msg);
204
- trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes);
217
+ trace_nfs_initiate_read(hdr);
205218 }
206219
207220 static void
....@@ -212,7 +225,7 @@
212225 while (!list_empty(head)) {
213226 req = nfs_list_entry(head->next);
214227 nfs_list_remove_request(req);
215
- nfs_readpage_release(req);
228
+ nfs_readpage_release(req, error);
216229 }
217230 }
218231
....@@ -234,11 +247,10 @@
234247 return status;
235248
236249 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count);
237
- trace_nfs_readpage_done(inode, task->tk_status,
238
- hdr->args.offset, hdr->res.eof);
250
+ trace_nfs_readpage_done(task, hdr);
239251
240252 if (task->tk_status == -ESTALE) {
241
- set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
253
+ nfs_set_inode_stale(inode);
242254 nfs_mark_for_revalidate(inode);
243255 }
244256 return 0;
....@@ -252,6 +264,8 @@
252264
253265 /* This is a short read! */
254266 nfs_inc_stats(hdr->inode, NFSIOS_SHORTREAD);
267
+ trace_nfs_readpage_short(task, hdr);
268
+
255269 /* Has the server at least made some progress? */
256270 if (resp->count == 0) {
257271 nfs_set_pgio_error(hdr, -EIO, argp->offset);
....@@ -269,6 +283,8 @@
269283 argp->offset += resp->count;
270284 argp->pgbase += resp->count;
271285 argp->count -= resp->count;
286
+ resp->count = 0;
287
+ resp->eof = 0;
272288 rpc_restart_call_prepare(task);
273289 }
274290
....@@ -276,16 +292,14 @@
276292 struct nfs_pgio_header *hdr)
277293 {
278294 if (hdr->res.eof) {
279
- loff_t bound;
295
+ loff_t pos = hdr->args.offset + hdr->res.count;
296
+ unsigned int new = pos - hdr->io_start;
280297
281
- bound = hdr->args.offset + hdr->res.count;
282
- spin_lock(&hdr->lock);
283
- if (bound < hdr->io_start + hdr->good_bytes) {
298
+ if (hdr->good_bytes > new) {
299
+ hdr->good_bytes = new;
284300 set_bit(NFS_IOHDR_EOF, &hdr->flags);
285301 clear_bit(NFS_IOHDR_ERROR, &hdr->flags);
286
- hdr->good_bytes = bound - hdr->io_start;
287302 }
288
- spin_unlock(&hdr->lock);
289303 } else if (hdr->res.count < hdr->args.count)
290304 nfs_readpage_retry(task, hdr);
291305 }
....@@ -338,8 +352,13 @@
338352 goto out;
339353 }
340354
355
+ xchg(&ctx->error, 0);
341356 error = nfs_readpage_async(ctx, inode, page);
342
-
357
+ if (!error) {
358
+ error = wait_on_page_locked_killable(page);
359
+ if (!PageUptodate(page) && !error)
360
+ error = xchg(&ctx->error, 0);
361
+ }
343362 out:
344363 put_nfs_open_context(ctx);
345364 return error;
....@@ -365,7 +384,7 @@
365384 if (len == 0)
366385 return nfs_return_empty_page(page);
367386
368
- new = nfs_create_request(desc->ctx, page, NULL, 0, len);
387
+ new = nfs_create_request(desc->ctx, page, 0, len);
369388 if (IS_ERR(new))
370389 goto out_error;
371390
....@@ -373,8 +392,8 @@
373392 zero_user_segment(page, len, PAGE_SIZE);
374393 if (!nfs_pageio_add_request(desc->pgio, new)) {
375394 nfs_list_remove_request(new);
376
- nfs_readpage_release(new);
377395 error = desc->pgio->pg_error;
396
+ nfs_readpage_release(new, error);
378397 goto out;
379398 }
380399 return 0;