aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
authorTigran Mkrtchyan <kofemann@gmail.com>2012-02-13 16:55:24 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-02-15 11:20:38 -0500
commit8b70484c67cf5241cfbea0ee31b83e42e5bac163 (patch)
tree2625d76be0ddbc5b1c27ca5aca96006482e49747 /fs/nfsd/nfs4proc.c
parent19ff0f288c6f2100987408ecc2cb911a2d50bc76 (diff)
nfsd41: handle current stateid in open and close
Signed-off-by: Tigran Mkrtchyan <kofemann@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r--fs/nfsd/nfs4proc.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 896da74ec563..b08f6e50fc48 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -39,6 +39,7 @@
39#include "cache.h" 39#include "cache.h"
40#include "xdr4.h" 40#include "xdr4.h"
41#include "vfs.h" 41#include "vfs.h"
42#include "current_stateid.h"
42 43
43#define NFSDDBG_FACILITY NFSDDBG_PROC 44#define NFSDDBG_FACILITY NFSDDBG_PROC
44 45
@@ -1000,6 +1001,8 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
1000typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1001typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
1001 void *); 1002 void *);
1002typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); 1003typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
1004typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *);
1005typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *);
1003 1006
1004enum nfsd4_op_flags { 1007enum nfsd4_op_flags {
1005 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 1008 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
@@ -1025,6 +1028,10 @@ enum nfsd4_op_flags {
1025 * the v4.0 case). 1028 * the v4.0 case).
1026 */ 1029 */
1027 OP_CACHEME = 1 << 6, 1030 OP_CACHEME = 1 << 6,
1031 /*
1032 * These are ops which clear current state id.
1033 */
1034 OP_CLEAR_STATEID = 1 << 7,
1028}; 1035};
1029 1036
1030struct nfsd4_operation { 1037struct nfsd4_operation {
@@ -1033,6 +1040,8 @@ struct nfsd4_operation {
1033 char *op_name; 1040 char *op_name;
1034 /* Try to get response size before operation */ 1041 /* Try to get response size before operation */
1035 nfsd4op_rsize op_rsize_bop; 1042 nfsd4op_rsize op_rsize_bop;
1043 stateid_setter op_get_currentstateid;
1044 stateid_getter op_set_currentstateid;
1036}; 1045};
1037 1046
1038static struct nfsd4_operation nfsd4_ops[]; 1047static struct nfsd4_operation nfsd4_ops[];
@@ -1215,13 +1224,23 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1215 if (op->status) 1224 if (op->status)
1216 goto encode_op; 1225 goto encode_op;
1217 1226
1218 if (opdesc->op_func) 1227 if (opdesc->op_func) {
1228 if (opdesc->op_get_currentstateid)
1229 opdesc->op_get_currentstateid(cstate, &op->u);
1219 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1230 op->status = opdesc->op_func(rqstp, cstate, &op->u);
1220 else 1231 } else
1221 BUG_ON(op->status == nfs_ok); 1232 BUG_ON(op->status == nfs_ok);
1222 1233
1223 if (!op->status && need_wrongsec_check(rqstp)) 1234 if (!op->status) {
1224 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); 1235 if (opdesc->op_set_currentstateid)
1236 opdesc->op_set_currentstateid(cstate, &op->u);
1237
1238 if (opdesc->op_flags & OP_CLEAR_STATEID)
1239 cstate->current_stateid = NULL;
1240
1241 if (need_wrongsec_check(rqstp))
1242 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp);
1243 }
1225 1244
1226encode_op: 1245encode_op:
1227 /* Only from SEQUENCE */ 1246 /* Only from SEQUENCE */
@@ -1413,6 +1432,8 @@ static struct nfsd4_operation nfsd4_ops[] = {
1413 .op_flags = OP_MODIFIES_SOMETHING, 1432 .op_flags = OP_MODIFIES_SOMETHING,
1414 .op_name = "OP_CLOSE", 1433 .op_name = "OP_CLOSE",
1415 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1434 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1435 .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid,
1436 .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid,
1416 }, 1437 },
1417 [OP_COMMIT] = { 1438 [OP_COMMIT] = {
1418 .op_func = (nfsd4op_func)nfsd4_commit, 1439 .op_func = (nfsd4op_func)nfsd4_commit,
@@ -1483,6 +1504,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1483 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, 1504 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
1484 .op_name = "OP_OPEN", 1505 .op_name = "OP_OPEN",
1485 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, 1506 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize,
1507 .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid,
1486 }, 1508 },
1487 [OP_OPEN_CONFIRM] = { 1509 [OP_OPEN_CONFIRM] = {
1488 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1510 .op_func = (nfsd4op_func)nfsd4_open_confirm,