aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 8e672a2b2d69..17149a490065 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1166,6 +1166,33 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1166} 1166}
1167EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); 1167EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
1168 1168
1169static int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head)
1170{
1171 struct nfs_pageio_descriptor pgio;
1172 LIST_HEAD(failed);
1173
1174 /* Resend all requests through the MDS */
1175 nfs_pageio_init_write_mds(&pgio, inode, FLUSH_STABLE);
1176 while (!list_empty(head)) {
1177 struct nfs_page *req = nfs_list_entry(head->next);
1178
1179 nfs_list_remove_request(req);
1180 if (!nfs_pageio_add_request(&pgio, req))
1181 nfs_list_add_request(req, &failed);
1182 }
1183 nfs_pageio_complete(&pgio);
1184
1185 if (!list_empty(&failed)) {
1186 /* For some reason our attempt to resend pages. Mark the
1187 * overall send request as having failed, and let
1188 * nfs_writeback_release_full deal with the error.
1189 */
1190 list_move(&failed, head);
1191 return -EIO;
1192 }
1193 return 0;
1194}
1195
1169/* 1196/*
1170 * Called by non rpc-based layout drivers 1197 * Called by non rpc-based layout drivers
1171 */ 1198 */
@@ -1175,9 +1202,17 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
1175 pnfs_set_layoutcommit(data); 1202 pnfs_set_layoutcommit(data);
1176 data->mds_ops->rpc_call_done(&data->task, data); 1203 data->mds_ops->rpc_call_done(&data->task, data);
1177 } else { 1204 } else {
1178 put_lseg(data->lseg);
1179 data->lseg = NULL;
1180 dprintk("pnfs write error = %d\n", data->pnfs_error); 1205 dprintk("pnfs write error = %d\n", data->pnfs_error);
1206 if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
1207 PNFS_LAYOUTRET_ON_ERROR) {
1208 /* Don't lo_commit on error, Server will needs to
1209 * preform a file recovery.
1210 */
1211 clear_bit(NFS_INO_LAYOUTCOMMIT,
1212 &NFS_I(data->inode)->flags);
1213 pnfs_return_layout(data->inode);
1214 }
1215 data->task.tk_status = pnfs_write_done_resend_to_mds(data->inode, &data->pages);
1181 } 1216 }
1182 data->mds_ops->rpc_release(data); 1217 data->mds_ops->rpc_release(data);
1183} 1218}
@@ -1267,6 +1302,9 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
1267 put_lseg(data->lseg); 1302 put_lseg(data->lseg);
1268 data->lseg = NULL; 1303 data->lseg = NULL;
1269 dprintk("pnfs write error = %d\n", data->pnfs_error); 1304 dprintk("pnfs write error = %d\n", data->pnfs_error);
1305 if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
1306 PNFS_LAYOUTRET_ON_ERROR)
1307 pnfs_return_layout(data->inode);
1270 1308
1271 nfs_pageio_init_read_mds(&pgio, data->inode); 1309 nfs_pageio_init_read_mds(&pgio, data->inode);
1272 1310