diff options
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
| -rw-r--r-- | fs/nfs/nfs4filelayout.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 52d847212066..2e45fd9c02a3 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
| @@ -122,12 +122,21 @@ static void filelayout_reset_read(struct nfs_read_data *data) | |||
| 122 | } | 122 | } |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo) | ||
| 126 | { | ||
| 127 | if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) | ||
| 128 | return; | ||
| 129 | clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags); | ||
| 130 | pnfs_return_layout(inode); | ||
| 131 | } | ||
| 132 | |||
| 125 | static int filelayout_async_handle_error(struct rpc_task *task, | 133 | static int filelayout_async_handle_error(struct rpc_task *task, |
| 126 | struct nfs4_state *state, | 134 | struct nfs4_state *state, |
| 127 | struct nfs_client *clp, | 135 | struct nfs_client *clp, |
| 128 | struct pnfs_layout_segment *lseg) | 136 | struct pnfs_layout_segment *lseg) |
| 129 | { | 137 | { |
| 130 | struct inode *inode = lseg->pls_layout->plh_inode; | 138 | struct pnfs_layout_hdr *lo = lseg->pls_layout; |
| 139 | struct inode *inode = lo->plh_inode; | ||
| 131 | struct nfs_server *mds_server = NFS_SERVER(inode); | 140 | struct nfs_server *mds_server = NFS_SERVER(inode); |
| 132 | struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); | 141 | struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); |
| 133 | struct nfs_client *mds_client = mds_server->nfs_client; | 142 | struct nfs_client *mds_client = mds_server->nfs_client; |
| @@ -204,10 +213,8 @@ static int filelayout_async_handle_error(struct rpc_task *task, | |||
| 204 | dprintk("%s DS connection error %d\n", __func__, | 213 | dprintk("%s DS connection error %d\n", __func__, |
| 205 | task->tk_status); | 214 | task->tk_status); |
| 206 | nfs4_mark_deviceid_unavailable(devid); | 215 | nfs4_mark_deviceid_unavailable(devid); |
| 207 | clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags); | 216 | set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags); |
| 208 | _pnfs_return_layout(inode); | ||
| 209 | rpc_wake_up(&tbl->slot_tbl_waitq); | 217 | rpc_wake_up(&tbl->slot_tbl_waitq); |
| 210 | nfs4_ds_disconnect(clp); | ||
| 211 | /* fall through */ | 218 | /* fall through */ |
| 212 | default: | 219 | default: |
| 213 | reset: | 220 | reset: |
| @@ -331,7 +338,9 @@ static void filelayout_read_count_stats(struct rpc_task *task, void *data) | |||
| 331 | static void filelayout_read_release(void *data) | 338 | static void filelayout_read_release(void *data) |
| 332 | { | 339 | { |
| 333 | struct nfs_read_data *rdata = data; | 340 | struct nfs_read_data *rdata = data; |
| 341 | struct pnfs_layout_hdr *lo = rdata->header->lseg->pls_layout; | ||
| 334 | 342 | ||
| 343 | filelayout_fenceme(lo->plh_inode, lo); | ||
| 335 | nfs_put_client(rdata->ds_clp); | 344 | nfs_put_client(rdata->ds_clp); |
| 336 | rdata->header->mds_ops->rpc_release(data); | 345 | rdata->header->mds_ops->rpc_release(data); |
| 337 | } | 346 | } |
| @@ -429,7 +438,9 @@ static void filelayout_write_count_stats(struct rpc_task *task, void *data) | |||
| 429 | static void filelayout_write_release(void *data) | 438 | static void filelayout_write_release(void *data) |
| 430 | { | 439 | { |
| 431 | struct nfs_write_data *wdata = data; | 440 | struct nfs_write_data *wdata = data; |
| 441 | struct pnfs_layout_hdr *lo = wdata->header->lseg->pls_layout; | ||
| 432 | 442 | ||
| 443 | filelayout_fenceme(lo->plh_inode, lo); | ||
| 433 | nfs_put_client(wdata->ds_clp); | 444 | nfs_put_client(wdata->ds_clp); |
| 434 | wdata->header->mds_ops->rpc_release(data); | 445 | wdata->header->mds_ops->rpc_release(data); |
| 435 | } | 446 | } |
| @@ -739,7 +750,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
| 739 | goto out_err; | 750 | goto out_err; |
| 740 | 751 | ||
| 741 | if (fl->num_fh > 0) { | 752 | if (fl->num_fh > 0) { |
| 742 | fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), | 753 | fl->fh_array = kcalloc(fl->num_fh, sizeof(fl->fh_array[0]), |
| 743 | gfp_flags); | 754 | gfp_flags); |
| 744 | if (!fl->fh_array) | 755 | if (!fl->fh_array) |
| 745 | goto out_err; | 756 | goto out_err; |
