diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-10-11 13:43:38 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-10-15 10:49:43 -0400 |
commit | d527e5c15de8de813cd0a2ad0b769f68c6226938 (patch) | |
tree | b96a57f9c6a628d66b605b9f7ef7e579b01a35b1 /fs | |
parent | 8fcdc31b3d09bc348ff9bf752ae1291828756cfa (diff) |
NFSv4.1: Do not call pnfs_return_layout() from an rpciod context
Move the call to pnfs_return_layout() to the read and write rpc_release()
callbacks, so that it gets called from nfsiod, which is a more appropriate
context.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 18 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 1 |
2 files changed, 16 insertions, 3 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 816c2d0d133a..e7aee566861d 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,8 +213,7 @@ 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 | /* fall through */ | 218 | /* fall through */ |
211 | default: | 219 | default: |
@@ -330,7 +338,9 @@ static void filelayout_read_count_stats(struct rpc_task *task, void *data) | |||
330 | static void filelayout_read_release(void *data) | 338 | static void filelayout_read_release(void *data) |
331 | { | 339 | { |
332 | struct nfs_read_data *rdata = data; | 340 | struct nfs_read_data *rdata = data; |
341 | struct pnfs_layout_hdr *lo = rdata->header->lseg->pls_layout; | ||
333 | 342 | ||
343 | filelayout_fenceme(lo->plh_inode, lo); | ||
334 | nfs_put_client(rdata->ds_clp); | 344 | nfs_put_client(rdata->ds_clp); |
335 | rdata->header->mds_ops->rpc_release(data); | 345 | rdata->header->mds_ops->rpc_release(data); |
336 | } | 346 | } |
@@ -428,7 +438,9 @@ static void filelayout_write_count_stats(struct rpc_task *task, void *data) | |||
428 | static void filelayout_write_release(void *data) | 438 | static void filelayout_write_release(void *data) |
429 | { | 439 | { |
430 | struct nfs_write_data *wdata = data; | 440 | struct nfs_write_data *wdata = data; |
441 | struct pnfs_layout_hdr *lo = wdata->header->lseg->pls_layout; | ||
431 | 442 | ||
443 | filelayout_fenceme(lo->plh_inode, lo); | ||
432 | nfs_put_client(wdata->ds_clp); | 444 | nfs_put_client(wdata->ds_clp); |
433 | wdata->header->mds_ops->rpc_release(data); | 445 | wdata->header->mds_ops->rpc_release(data); |
434 | } | 446 | } |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 2d722dba1111..dbf7bba52da0 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -62,6 +62,7 @@ enum { | |||
62 | NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ | 62 | NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */ |
63 | NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ | 63 | NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */ |
64 | NFS_LAYOUT_ROC, /* some lseg had roc bit set */ | 64 | NFS_LAYOUT_ROC, /* some lseg had roc bit set */ |
65 | NFS_LAYOUT_RETURN, /* Return this layout ASAP */ | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | enum layoutdriver_policy_flags { | 68 | enum layoutdriver_policy_flags { |