aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-11 13:43:38 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-15 10:49:43 -0400
commitd527e5c15de8de813cd0a2ad0b769f68c6226938 (patch)
treeb96a57f9c6a628d66b605b9f7ef7e579b01a35b1 /fs
parent8fcdc31b3d09bc348ff9bf752ae1291828756cfa (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.c18
-rw-r--r--fs/nfs/pnfs.h1
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
125static 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
125static int filelayout_async_handle_error(struct rpc_task *task, 133static 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)
330static void filelayout_read_release(void *data) 338static 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)
428static void filelayout_write_release(void *data) 438static 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
67enum layoutdriver_policy_flags { 68enum layoutdriver_policy_flags {