NFSv4.1: Fix a race in the pNFS return-on-close code
If we sleep after dropping the inode->i_lock, then we are no longer atomic with respect to the rpc_wake_up() call in pnfs_layout_remove_lseg(). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
@@ -2137,6 +2137,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nfs4_closedata *calldata = data;
|
||||
struct nfs4_state *state = calldata->state;
|
||||
struct inode *inode = calldata->inode;
|
||||
int call_close = 0;
|
||||
|
||||
dprintk("%s: begin!\n", __func__);
|
||||
@@ -2170,16 +2171,13 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
|
||||
if (calldata->arg.fmode == 0) {
|
||||
task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
|
||||
if (calldata->roc &&
|
||||
pnfs_roc_drain(calldata->inode, &calldata->roc_barrier)) {
|
||||
rpc_sleep_on(&NFS_SERVER(calldata->inode)->roc_rpcwaitq,
|
||||
task, NULL);
|
||||
pnfs_roc_drain(inode, &calldata->roc_barrier, task))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
nfs_fattr_init(calldata->res.fattr);
|
||||
calldata->timestamp = jiffies;
|
||||
if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
|
||||
if (nfs4_setup_sequence(NFS_SERVER(inode),
|
||||
&calldata->arg.seq_args,
|
||||
&calldata->res.seq_res,
|
||||
task))
|
||||
|
Reference in New Issue
Block a user