diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-08-19 06:45:13 +0200 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-08-19 06:45:13 +0200 |
commit | 3c13cb5b647ebe36fb79128bc8b917d2a3317b65 (patch) | |
tree | 04fdc0eb8041c2123c4e605d6a259ea8cca012b8 /fs | |
parent | NFSv4.1/pnfs: Fix a close/delegreturn hang when return-on-close is set (diff) | |
download | linux-3c13cb5b647ebe36fb79128bc8b917d2a3317b65.tar.xz linux-3c13cb5b647ebe36fb79128bc8b917d2a3317b65.zip |
NFSv4.1/pnfs: Play safe w.r.t. close() races when return-on-close is set
If we have an OPEN_DOWNGRADE and CLOSE race with one another, we want
to ensure that the layout is forgotten by the client, so that we
start afresh with a new layoutget.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index bda7837dfe6b..9e9f7816cf24 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2661,7 +2661,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) switch (task->tk_status) { case 0: res_stateid = &calldata->res.stateid; - if (calldata->arg.fmode == 0 && calldata->roc) + if (calldata->roc) pnfs_roc_set_barrier(state->inode, calldata->roc_barrier); renew_lease(server, calldata->timestamp); @@ -2735,11 +2735,11 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) goto out_no_action; } - if (calldata->arg.fmode == 0) { + if (calldata->arg.fmode == 0) task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE]; - if (calldata->roc) - pnfs_roc_get_barrier(inode, &calldata->roc_barrier); - } + if (calldata->roc) + pnfs_roc_get_barrier(inode, &calldata->roc_barrier); + calldata->arg.share_access = nfs4_map_atomic_open_share(NFS_SERVER(inode), calldata->arg.fmode, 0); |