aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-16 18:42:34 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-16 18:58:26 -0400
commit549b19cc9f31e8fdda317625d564bac0052a3328 (patch)
tree4906e15f9d45a89cb6ea548837bc0cc6eee1f75f
parent98f98cf571b7b1f34683455a61dae9f35e7222a1 (diff)
NFSv4: Record the OPEN create mode used in the nfs4_opendata structure
If we're doing NFSv4.1 against a server that has persistent sessions, then we should not need to call SETATTR in order to reset the file attributes immediately after doing an exclusive create. Note that since the create mode depends on the type of session that has been negotiated with the server, we should not choose the mode until after we've got a session slot. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c16
-rw-r--r--fs/nfs/nfs4xdr.c37
-rw-r--r--include/linux/nfs_xdr.h1
3 files changed, 31 insertions, 23 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index af05df3c7c79..282d9fa6994a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1525,6 +1525,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1525{ 1525{
1526 struct nfs4_opendata *data = calldata; 1526 struct nfs4_opendata *data = calldata;
1527 struct nfs4_state_owner *sp = data->owner; 1527 struct nfs4_state_owner *sp = data->owner;
1528 struct nfs_client *clp = sp->so_server->nfs_client;
1528 1529
1529 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) 1530 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
1530 goto out_wait; 1531 goto out_wait;
@@ -1545,7 +1546,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1545 rcu_read_unlock(); 1546 rcu_read_unlock();
1546 } 1547 }
1547 /* Update client id. */ 1548 /* Update client id. */
1548 data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid; 1549 data->o_arg.clientid = clp->cl_clientid;
1549 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { 1550 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
1550 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; 1551 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
1551 data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0]; 1552 data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
@@ -1557,6 +1558,16 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1557 &data->o_res.seq_res, 1558 &data->o_res.seq_res,
1558 task) != 0) 1559 task) != 0)
1559 nfs_release_seqid(data->o_arg.seqid); 1560 nfs_release_seqid(data->o_arg.seqid);
1561
1562 /* Set the create mode (note dependency on the session type) */
1563 data->o_arg.createmode = NFS4_CREATE_UNCHECKED;
1564 if (data->o_arg.open_flags & O_EXCL) {
1565 data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE;
1566 if (nfs4_has_persistent_session(clp))
1567 data->o_arg.createmode = NFS4_CREATE_GUARDED;
1568 else if (clp->cl_mvops->minor_version > 0)
1569 data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1;
1570 }
1560 return; 1571 return;
1561unlock_no_action: 1572unlock_no_action:
1562 rcu_read_unlock(); 1573 rcu_read_unlock();
@@ -2000,7 +2011,8 @@ static int _nfs4_do_open(struct inode *dir,
2000 if (status != 0) 2011 if (status != 0)
2001 goto err_opendata_put; 2012 goto err_opendata_put;
2002 2013
2003 if (opendata->o_arg.open_flags & O_EXCL) { 2014 if ((opendata->o_arg.open_flags & O_EXCL) &&
2015 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
2004 nfs4_exclusive_attrset(opendata, sattr); 2016 nfs4_exclusive_attrset(opendata, sattr);
2005 2017
2006 nfs_fattr_init(opendata->o_res.f_attr); 2018 nfs_fattr_init(opendata->o_res.f_attr);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 0b744895b9e1..fef71cbec501 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1366,33 +1366,28 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
1366 1366
1367static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) 1367static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
1368{ 1368{
1369 struct iattr dummy;
1369 __be32 *p; 1370 __be32 *p;
1370 struct nfs_client *clp;
1371 1371
1372 p = reserve_space(xdr, 4); 1372 p = reserve_space(xdr, 4);
1373 switch(arg->open_flags & O_EXCL) { 1373 switch(arg->createmode) {
1374 case 0: 1374 case NFS4_CREATE_UNCHECKED:
1375 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 1375 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
1376 encode_attrs(xdr, arg->u.attrs, arg->server); 1376 encode_attrs(xdr, arg->u.attrs, arg->server);
1377 break; 1377 break;
1378 default: 1378 case NFS4_CREATE_GUARDED:
1379 clp = arg->server->nfs_client; 1379 *p = cpu_to_be32(NFS4_CREATE_GUARDED);
1380 if (clp->cl_mvops->minor_version > 0) { 1380 encode_attrs(xdr, arg->u.attrs, arg->server);
1381 if (nfs4_has_persistent_session(clp)) { 1381 break;
1382 *p = cpu_to_be32(NFS4_CREATE_GUARDED); 1382 case NFS4_CREATE_EXCLUSIVE:
1383 encode_attrs(xdr, arg->u.attrs, arg->server); 1383 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
1384 } else { 1384 encode_nfs4_verifier(xdr, &arg->u.verifier);
1385 struct iattr dummy; 1385 break;
1386 1386 case NFS4_CREATE_EXCLUSIVE4_1:
1387 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 1387 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
1388 encode_nfs4_verifier(xdr, &arg->u.verifier); 1388 encode_nfs4_verifier(xdr, &arg->u.verifier);
1389 dummy.ia_valid = 0; 1389 dummy.ia_valid = 0;
1390 encode_attrs(xdr, &dummy, arg->server); 1390 encode_attrs(xdr, &dummy, arg->server);
1391 }
1392 } else {
1393 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
1394 encode_nfs4_verifier(xdr, &arg->u.verifier);
1395 }
1396 } 1391 }
1397} 1392}
1398 1393
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 90a4aa190b43..bdc100f66dfb 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -349,6 +349,7 @@ struct nfs_openargs {
349 const u32 * bitmask; 349 const u32 * bitmask;
350 const u32 * open_bitmap; 350 const u32 * open_bitmap;
351 __u32 claim; 351 __u32 claim;
352 enum createmode4 createmode;
352}; 353};
353 354
354struct nfs_openres { 355struct nfs_openres {