]>
Commit | Line | Data |
---|---|---|
ecf3b270 SL |
1 | From b6f8a3bead3e19044c4b76809c15be1ec22948ce Mon Sep 17 00:00:00 2001 |
2 | From: Benjamin Coddington <bcodding@redhat.com> | |
3 | Date: Wed, 6 Feb 2019 06:09:43 -0500 | |
4 | Subject: NFS: Don't use page_file_mapping after removing the page | |
5 | ||
6 | [ Upstream commit d2ceb7e57086750ea6198a31fd942d98099a0786 ] | |
7 | ||
8 | If nfs_page_async_flush() removes the page from the mapping, then we can't | |
9 | use page_file_mapping() on it as nfs_updatepate() is wont to do when | |
10 | receiving an error. Instead, push the mapping to the stack before the page | |
11 | is possibly truncated. | |
12 | ||
13 | Fixes: 8fc75bed96bb ("NFS: Fix up return value on fatal errors in nfs_page_async_flush()") | |
14 | Signed-off-by: Benjamin Coddington <bcodding@redhat.com> | |
15 | Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> | |
16 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
17 | --- | |
18 | fs/nfs/write.c | 11 ++++++----- | |
19 | 1 file changed, 6 insertions(+), 5 deletions(-) | |
20 | ||
21 | diff --git a/fs/nfs/write.c b/fs/nfs/write.c | |
22 | index 2d956a7d5378..50ed3944d183 100644 | |
23 | --- a/fs/nfs/write.c | |
24 | +++ b/fs/nfs/write.c | |
25 | @@ -236,9 +236,9 @@ out: | |
26 | } | |
27 | ||
28 | /* A writeback failed: mark the page as bad, and invalidate the page cache */ | |
29 | -static void nfs_set_pageerror(struct page *page) | |
30 | +static void nfs_set_pageerror(struct address_space *mapping) | |
31 | { | |
32 | - nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page)); | |
33 | + nfs_zap_mapping(mapping->host, mapping); | |
34 | } | |
35 | ||
36 | /* | |
37 | @@ -994,7 +994,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr) | |
38 | nfs_list_remove_request(req); | |
39 | if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && | |
40 | (hdr->good_bytes < bytes)) { | |
41 | - nfs_set_pageerror(req->wb_page); | |
42 | + nfs_set_pageerror(page_file_mapping(req->wb_page)); | |
43 | nfs_context_set_write_error(req->wb_context, hdr->error); | |
44 | goto remove_req; | |
45 | } | |
46 | @@ -1330,7 +1330,8 @@ int nfs_updatepage(struct file *file, struct page *page, | |
47 | unsigned int offset, unsigned int count) | |
48 | { | |
49 | struct nfs_open_context *ctx = nfs_file_open_context(file); | |
50 | - struct inode *inode = page_file_mapping(page)->host; | |
51 | + struct address_space *mapping = page_file_mapping(page); | |
52 | + struct inode *inode = mapping->host; | |
53 | int status = 0; | |
54 | ||
55 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); | |
56 | @@ -1348,7 +1349,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |
57 | ||
58 | status = nfs_writepage_setup(ctx, page, offset, count); | |
59 | if (status < 0) | |
60 | - nfs_set_pageerror(page); | |
61 | + nfs_set_pageerror(mapping); | |
62 | else | |
63 | __set_page_dirty_nobuffers(page); | |
64 | out: | |
65 | -- | |
66 | 2.19.1 | |
67 |