]>
Commit | Line | Data |
---|---|---|
4bc507ef GKH |
1 | From 8ce160c5ef06cc89c2b6b26bfa5ef7a5ce2c93e0 Mon Sep 17 00:00:00 2001 |
2 | From: Peng Tao <bergwolf@gmail.com> | |
3 | Date: Thu, 22 Sep 2011 21:50:14 -0400 | |
4 | Subject: pnfs: recoalesce when ld write pagelist fails | |
5 | ||
6 | From: Peng Tao <bergwolf@gmail.com> | |
7 | ||
8 | commit 8ce160c5ef06cc89c2b6b26bfa5ef7a5ce2c93e0 upstream. | |
9 | ||
10 | For pnfs pagelist write failure, we need to pg_recoalesce and resend IO to | |
11 | mds. | |
12 | ||
13 | Signed-off-by: Peng Tao <peng_tao@emc.com> | |
14 | Signed-off-by: Jim Rees <rees@umich.edu> | |
15 | Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> | |
16 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
17 | ||
18 | --- | |
19 | fs/nfs/pnfs.c | 20 +++++++------------- | |
20 | fs/nfs/pnfs.h | 2 +- | |
21 | fs/nfs/write.c | 25 ++++++++++++++++++++++++- | |
22 | 3 files changed, 32 insertions(+), 15 deletions(-) | |
23 | ||
24 | --- a/fs/nfs/pnfs.c | |
25 | +++ b/fs/nfs/pnfs.c | |
26 | @@ -1168,23 +1168,17 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); | |
27 | /* | |
28 | * Called by non rpc-based layout drivers | |
29 | */ | |
30 | -int | |
31 | -pnfs_ld_write_done(struct nfs_write_data *data) | |
32 | +void pnfs_ld_write_done(struct nfs_write_data *data) | |
33 | { | |
34 | - int status; | |
35 | - | |
36 | - if (!data->pnfs_error) { | |
37 | + if (likely(!data->pnfs_error)) { | |
38 | pnfs_set_layoutcommit(data); | |
39 | data->mds_ops->rpc_call_done(&data->task, data); | |
40 | - data->mds_ops->rpc_release(data); | |
41 | - return 0; | |
42 | + } else { | |
43 | + put_lseg(data->lseg); | |
44 | + data->lseg = NULL; | |
45 | + dprintk("pnfs write error = %d\n", data->pnfs_error); | |
46 | } | |
47 | - | |
48 | - dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, | |
49 | - data->pnfs_error); | |
50 | - status = nfs_initiate_write(data, NFS_CLIENT(data->inode), | |
51 | - data->mds_ops, NFS_FILE_SYNC); | |
52 | - return status ? : -EAGAIN; | |
53 | + data->mds_ops->rpc_release(data); | |
54 | } | |
55 | EXPORT_SYMBOL_GPL(pnfs_ld_write_done); | |
56 | ||
57 | --- a/fs/nfs/pnfs.h | |
58 | +++ b/fs/nfs/pnfs.h | |
59 | @@ -201,7 +201,7 @@ void pnfs_set_layoutcommit(struct nfs_wr | |
60 | void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data); | |
61 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); | |
62 | int _pnfs_return_layout(struct inode *); | |
63 | -int pnfs_ld_write_done(struct nfs_write_data *); | |
64 | +void pnfs_ld_write_done(struct nfs_write_data *); | |
65 | int pnfs_ld_read_done(struct nfs_read_data *); | |
66 | struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino, | |
67 | struct nfs_open_context *ctx, | |
68 | --- a/fs/nfs/write.c | |
69 | +++ b/fs/nfs/write.c | |
70 | @@ -1165,7 +1165,13 @@ static void nfs_writeback_done_full(stru | |
71 | static void nfs_writeback_release_full(void *calldata) | |
72 | { | |
73 | struct nfs_write_data *data = calldata; | |
74 | - int status = data->task.tk_status; | |
75 | + int ret, status = data->task.tk_status; | |
76 | + struct nfs_pageio_descriptor pgio; | |
77 | + | |
78 | + if (data->pnfs_error) { | |
79 | + nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE); | |
80 | + pgio.pg_recoalesce = 1; | |
81 | + } | |
82 | ||
83 | /* Update attributes as result of writeback. */ | |
84 | while (!list_empty(&data->pages)) { | |
85 | @@ -1181,6 +1187,11 @@ static void nfs_writeback_release_full(v | |
86 | req->wb_bytes, | |
87 | (long long)req_offset(req)); | |
88 | ||
89 | + if (data->pnfs_error) { | |
90 | + dprintk(", pnfs error = %d\n", data->pnfs_error); | |
91 | + goto next; | |
92 | + } | |
93 | + | |
94 | if (status < 0) { | |
95 | nfs_set_pageerror(page); | |
96 | nfs_context_set_write_error(req->wb_context, status); | |
97 | @@ -1200,7 +1211,19 @@ remove_request: | |
98 | next: | |
99 | nfs_clear_page_tag_locked(req); | |
100 | nfs_end_page_writeback(page); | |
101 | + if (data->pnfs_error) { | |
102 | + lock_page(page); | |
103 | + nfs_pageio_cond_complete(&pgio, page->index); | |
104 | + ret = nfs_page_async_flush(&pgio, page, 0); | |
105 | + if (ret) { | |
106 | + nfs_set_pageerror(page); | |
107 | + dprintk("rewrite to MDS error = %d\n", ret); | |
108 | + } | |
109 | + unlock_page(page); | |
110 | + } | |
111 | } | |
112 | + if (data->pnfs_error) | |
113 | + nfs_pageio_complete(&pgio); | |
114 | nfs_writedata_release(calldata); | |
115 | } | |
116 |