aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2012-04-27 17:53:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-19 17:54:20 -0400
commite7dd79af01e7ca932c5168a708e77750659f7a9e (patch)
treedfacd16bce6df877ecae697cd7dbf5f8e0561872 /fs/nfs/nfs4filelayout.c
parent98fc685ae2aa24eae98526e9196b3229d519083a (diff)
NFSv4.1: mark deviceid invalid on filelayout DS connection errors
This prevents the use of any layout for i/o that references the deviceid. I/O is redirected through the MDS. Redirect the unhandled failed I/O to the MDS without marking either the layout or the deviceid invalid. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c130
1 files changed, 97 insertions, 33 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 0db8c0783039..f503cbe5a21a 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -82,29 +82,77 @@ filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset)
82 BUG(); 82 BUG();
83} 83}
84 84
85static void filelayout_reset_write(struct nfs_write_data *data)
86{
87 struct nfs_pgio_header *hdr = data->header;
88 struct inode *inode = hdr->inode;
89 struct rpc_task *task = &data->task;
90
91 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
92 dprintk("%s Reset task %5u for i/o through MDS "
93 "(req %s/%lld, %u bytes @ offset %llu)\n", __func__,
94 data->task.tk_pid,
95 inode->i_sb->s_id,
96 (long long)NFS_FILEID(inode),
97 data->args.count,
98 (unsigned long long)data->args.offset);
99
100 task->tk_status = pnfs_write_done_resend_to_mds(hdr->inode,
101 &hdr->pages,
102 hdr->completion_ops);
103 }
104}
105
106static void filelayout_reset_read(struct nfs_read_data *data)
107{
108 struct nfs_pgio_header *hdr = data->header;
109 struct inode *inode = hdr->inode;
110 struct rpc_task *task = &data->task;
111
112 if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
113 dprintk("%s Reset task %5u for i/o through MDS "
114 "(req %s/%lld, %u bytes @ offset %llu)\n", __func__,
115 data->task.tk_pid,
116 inode->i_sb->s_id,
117 (long long)NFS_FILEID(inode),
118 data->args.count,
119 (unsigned long long)data->args.offset);
120
121 task->tk_status = pnfs_read_done_resend_to_mds(hdr->inode,
122 &hdr->pages,
123 hdr->completion_ops);
124 }
125}
126
85static int filelayout_async_handle_error(struct rpc_task *task, 127static int filelayout_async_handle_error(struct rpc_task *task,
86 struct nfs4_state *state, 128 struct nfs4_state *state,
87 struct nfs_client *clp, 129 struct nfs_client *clp,
88 int *reset) 130 struct pnfs_layout_segment *lseg)
89{ 131{
90 struct nfs_server *mds_server = NFS_SERVER(state->inode); 132 struct inode *inode = lseg->pls_layout->plh_inode;
133 struct nfs_server *mds_server = NFS_SERVER(inode);
134 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
91 struct nfs_client *mds_client = mds_server->nfs_client; 135 struct nfs_client *mds_client = mds_server->nfs_client;
92 136
93 if (task->tk_status >= 0) 137 if (task->tk_status >= 0)
94 return 0; 138 return 0;
95 *reset = 0;
96 139
97 switch (task->tk_status) { 140 switch (task->tk_status) {
98 /* MDS state errors */ 141 /* MDS state errors */
99 case -NFS4ERR_DELEG_REVOKED: 142 case -NFS4ERR_DELEG_REVOKED:
100 case -NFS4ERR_ADMIN_REVOKED: 143 case -NFS4ERR_ADMIN_REVOKED:
101 case -NFS4ERR_BAD_STATEID: 144 case -NFS4ERR_BAD_STATEID:
145 if (state == NULL)
146 break;
102 nfs_remove_bad_delegation(state->inode); 147 nfs_remove_bad_delegation(state->inode);
103 case -NFS4ERR_OPENMODE: 148 case -NFS4ERR_OPENMODE:
149 if (state == NULL)
150 break;
104 nfs4_schedule_stateid_recovery(mds_server, state); 151 nfs4_schedule_stateid_recovery(mds_server, state);
105 goto wait_on_recovery; 152 goto wait_on_recovery;
106 case -NFS4ERR_EXPIRED: 153 case -NFS4ERR_EXPIRED:
107 nfs4_schedule_stateid_recovery(mds_server, state); 154 if (state != NULL)
155 nfs4_schedule_stateid_recovery(mds_server, state);
108 nfs4_schedule_lease_recovery(mds_client); 156 nfs4_schedule_lease_recovery(mds_client);
109 goto wait_on_recovery; 157 goto wait_on_recovery;
110 /* DS session errors */ 158 /* DS session errors */
@@ -127,11 +175,22 @@ static int filelayout_async_handle_error(struct rpc_task *task,
127 break; 175 break;
128 case -NFS4ERR_RETRY_UNCACHED_REP: 176 case -NFS4ERR_RETRY_UNCACHED_REP:
129 break; 177 break;
178 /* RPC connection errors */
179 case -ECONNREFUSED:
180 case -EHOSTDOWN:
181 case -EHOSTUNREACH:
182 case -ENETUNREACH:
183 case -EIO:
184 case -ETIMEDOUT:
185 case -EPIPE:
186 dprintk("%s DS connection error %d\n", __func__,
187 task->tk_status);
188 filelayout_mark_devid_invalid(devid);
189 /* fall through */
130 default: 190 default:
131 dprintk("%s DS error. Retry through MDS %d\n", __func__, 191 dprintk("%s Retry through MDS. Error %d\n", __func__,
132 task->tk_status); 192 task->tk_status);
133 *reset = 1; 193 return -NFS4ERR_RESET_TO_MDS;
134 break;
135 } 194 }
136out: 195out:
137 task->tk_status = 0; 196 task->tk_status = 0;
@@ -148,16 +207,17 @@ wait_on_recovery:
148static int filelayout_read_done_cb(struct rpc_task *task, 207static int filelayout_read_done_cb(struct rpc_task *task,
149 struct nfs_read_data *data) 208 struct nfs_read_data *data)
150{ 209{
151 int reset = 0; 210 struct nfs_pgio_header *hdr = data->header;
211 int err;
152 212
153 dprintk("%s DS read\n", __func__); 213 err = filelayout_async_handle_error(task, data->args.context->state,
214 data->ds_clp, hdr->lseg);
154 215
155 if (filelayout_async_handle_error(task, data->args.context->state, 216 switch (err) {
156 data->ds_clp, &reset) == -EAGAIN) { 217 case -NFS4ERR_RESET_TO_MDS:
157 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 218 filelayout_reset_read(data);
158 __func__, data->ds_clp, data->ds_clp->cl_session); 219 return task->tk_status;
159 if (reset) 220 case -EAGAIN:
160 nfs4_reset_read(task, data);
161 rpc_restart_call_prepare(task); 221 rpc_restart_call_prepare(task);
162 return -EAGAIN; 222 return -EAGAIN;
163 } 223 }
@@ -230,14 +290,17 @@ static void filelayout_read_release(void *data)
230static int filelayout_write_done_cb(struct rpc_task *task, 290static int filelayout_write_done_cb(struct rpc_task *task,
231 struct nfs_write_data *data) 291 struct nfs_write_data *data)
232{ 292{
233 int reset = 0; 293 struct nfs_pgio_header *hdr = data->header;
234 294 int err;
235 if (filelayout_async_handle_error(task, data->args.context->state, 295
236 data->ds_clp, &reset) == -EAGAIN) { 296 err = filelayout_async_handle_error(task, data->args.context->state,
237 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 297 data->ds_clp, hdr->lseg);
238 __func__, data->ds_clp, data->ds_clp->cl_session); 298
239 if (reset) 299 switch (err) {
240 nfs4_reset_write(task, data); 300 case -NFS4ERR_RESET_TO_MDS:
301 filelayout_reset_write(data);
302 return task->tk_status;
303 case -EAGAIN:
241 rpc_restart_call_prepare(task); 304 rpc_restart_call_prepare(task);
242 return -EAGAIN; 305 return -EAGAIN;
243 } 306 }
@@ -260,16 +323,17 @@ static void prepare_to_resend_writes(struct nfs_commit_data *data)
260static int filelayout_commit_done_cb(struct rpc_task *task, 323static int filelayout_commit_done_cb(struct rpc_task *task,
261 struct nfs_commit_data *data) 324 struct nfs_commit_data *data)
262{ 325{
263 int reset = 0; 326 int err;
264 327
265 if (filelayout_async_handle_error(task, data->context->state, 328 err = filelayout_async_handle_error(task, NULL, data->ds_clp,
266 data->ds_clp, &reset) == -EAGAIN) { 329 data->lseg);
267 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 330
268 __func__, data->ds_clp, data->ds_clp->cl_session); 331 switch (err) {
269 if (reset) 332 case -NFS4ERR_RESET_TO_MDS:
270 prepare_to_resend_writes(data); 333 prepare_to_resend_writes(data);
271 else 334 return -EAGAIN;
272 rpc_restart_call_prepare(task); 335 case -EAGAIN:
336 rpc_restart_call_prepare(task);
273 return -EAGAIN; 337 return -EAGAIN;
274 } 338 }
275 339