aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-18 18:03:27 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-19 17:19:25 -0400
commita49c3c7736a2e77931dabc5bc4a83fb4b2da013e (patch)
tree1921900be210540ee53a4011c9e8f781deb0367e /fs/nfs/nfs4proc.c
parent565277f63c616e11c37309a1e98c052d18ebbb55 (diff)
NFSv4: Ensure that we wait for the CLOSE request to complete
Otherwise, we do end up breaking close-to-open semantics. We also end up breaking some of the silly-rename tests in Connectathon on some setups. Please refer to the bug-report at http://bugzilla.linux-nfs.org/show_bug.cgi?id=150 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2cb3b8b71ee7..f03d9d5f5ba4 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1305,7 +1305,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
1305 * 1305 *
1306 * NOTE: Caller must be holding the sp->so_owner semaphore! 1306 * NOTE: Caller must be holding the sp->so_owner semaphore!
1307 */ 1307 */
1308int nfs4_do_close(struct path *path, struct nfs4_state *state) 1308int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1309{ 1309{
1310 struct nfs_server *server = NFS_SERVER(state->inode); 1310 struct nfs_server *server = NFS_SERVER(state->inode);
1311 struct nfs4_closedata *calldata; 1311 struct nfs4_closedata *calldata;
@@ -1333,8 +1333,11 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state)
1333 task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata); 1333 task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
1334 if (IS_ERR(task)) 1334 if (IS_ERR(task))
1335 return PTR_ERR(task); 1335 return PTR_ERR(task);
1336 status = 0;
1337 if (wait)
1338 status = rpc_wait_for_completion_task(task);
1336 rpc_put_task(task); 1339 rpc_put_task(task);
1337 return 0; 1340 return status;
1338out_free_calldata: 1341out_free_calldata:
1339 kfree(calldata); 1342 kfree(calldata);
1340out: 1343out:
@@ -1365,7 +1368,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
1365 } 1368 }
1366 ret = PTR_ERR(filp); 1369 ret = PTR_ERR(filp);
1367out_close: 1370out_close:
1368 nfs4_close_state(path, state, nd->intent.open.flags); 1371 nfs4_close_sync(path, state, nd->intent.open.flags);
1369 return ret; 1372 return ret;
1370} 1373}
1371 1374
@@ -1450,7 +1453,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1450 nfs4_intent_set_file(nd, &path, state); 1453 nfs4_intent_set_file(nd, &path, state);
1451 return 1; 1454 return 1;
1452 } 1455 }
1453 nfs4_close_state(&path, state, openflags); 1456 nfs4_close_sync(&path, state, openflags);
1454out_drop: 1457out_drop:
1455 d_drop(dentry); 1458 d_drop(dentry);
1456 return 0; 1459 return 0;
@@ -1904,7 +1907,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1904 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) 1907 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
1905 status = nfs4_intent_set_file(nd, &path, state); 1908 status = nfs4_intent_set_file(nd, &path, state);
1906 else 1909 else
1907 nfs4_close_state(&path, state, flags); 1910 nfs4_close_sync(&path, state, flags);
1908out: 1911out:
1909 return status; 1912 return status;
1910} 1913}