aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/current_stateid.h28
-rw-r--r--fs/nfsd/export.c2
-rw-r--r--fs/nfsd/nfs4callback.c2
-rw-r--r--fs/nfsd/nfs4proc.c115
-rw-r--r--fs/nfsd/nfs4state.c309
-rw-r--r--fs/nfsd/nfs4xdr.c132
-rw-r--r--fs/nfsd/nfssvc.c44
-rw-r--r--fs/nfsd/state.h21
-rw-r--r--fs/nfsd/vfs.c33
-rw-r--r--fs/nfsd/vfs.h2
-rw-r--r--fs/nfsd/xdr4.h34
11 files changed, 518 insertions, 204 deletions
diff --git a/fs/nfsd/current_stateid.h b/fs/nfsd/current_stateid.h
new file mode 100644
index 000000000000..4123551208d8
--- /dev/null
+++ b/fs/nfsd/current_stateid.h
@@ -0,0 +1,28 @@
1#ifndef _NFSD4_CURRENT_STATE_H
2#define _NFSD4_CURRENT_STATE_H
3
4#include "state.h"
5#include "xdr4.h"
6
7extern void clear_current_stateid(struct nfsd4_compound_state *cstate);
8/*
9 * functions to set current state id
10 */
11extern void nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *);
12extern void nfsd4_set_openstateid(struct nfsd4_compound_state *, struct nfsd4_open *);
13extern void nfsd4_set_lockstateid(struct nfsd4_compound_state *, struct nfsd4_lock *);
14extern void nfsd4_set_closestateid(struct nfsd4_compound_state *, struct nfsd4_close *);
15
16/*
17 * functions to consume current state id
18 */
19extern void nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *);
20extern void nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *, struct nfsd4_delegreturn *);
21extern void nfsd4_get_freestateid(struct nfsd4_compound_state *, struct nfsd4_free_stateid *);
22extern void nfsd4_get_setattrstateid(struct nfsd4_compound_state *, struct nfsd4_setattr *);
23extern void nfsd4_get_closestateid(struct nfsd4_compound_state *, struct nfsd4_close *);
24extern void nfsd4_get_lockustateid(struct nfsd4_compound_state *, struct nfsd4_locku *);
25extern void nfsd4_get_readstateid(struct nfsd4_compound_state *, struct nfsd4_read *);
26extern void nfsd4_get_writestateid(struct nfsd4_compound_state *, struct nfsd4_write *);
27
28#endif /* _NFSD4_CURRENT_STATE_H */
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index cf8a6bd062fa..8e9689abbc0c 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -87,7 +87,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
87 struct svc_expkey key; 87 struct svc_expkey key;
88 struct svc_expkey *ek = NULL; 88 struct svc_expkey *ek = NULL;
89 89
90 if (mlen < 1 || mesg[mlen-1] != '\n') 90 if (mesg[mlen - 1] != '\n')
91 return -EINVAL; 91 return -EINVAL;
92 mesg[mlen-1] = 0; 92 mesg[mlen-1] = 0;
93 93
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 0e262f32ac41..cf6e4190e41c 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -986,7 +986,7 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
986 986
987 err = setup_callback_client(clp, &conn, ses); 987 err = setup_callback_client(clp, &conn, ses);
988 if (err) { 988 if (err) {
989 warn_no_callback_path(clp, err); 989 nfsd4_mark_cb_down(clp, err);
990 return; 990 return;
991 } 991 }
992 /* Yay, the callback channel's back! Restart any callbacks: */ 992 /* Yay, the callback channel's back! Restart any callbacks: */
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 896da74ec563..2a9036670b8f 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
@@ -192,10 +193,13 @@ static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
192static __be32 193static __be32
193do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 194do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
194{ 195{
195 struct svc_fh resfh; 196 struct svc_fh *resfh;
196 __be32 status; 197 __be32 status;
197 198
198 fh_init(&resfh, NFS4_FHSIZE); 199 resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
200 if (!resfh)
201 return nfserr_jukebox;
202 fh_init(resfh, NFS4_FHSIZE);
199 open->op_truncate = 0; 203 open->op_truncate = 0;
200 204
201 if (open->op_create) { 205 if (open->op_create) {
@@ -220,7 +224,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
220 */ 224 */
221 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, 225 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
222 open->op_fname.len, &open->op_iattr, 226 open->op_fname.len, &open->op_iattr,
223 &resfh, open->op_createmode, 227 resfh, open->op_createmode,
224 (u32 *)open->op_verf.data, 228 (u32 *)open->op_verf.data,
225 &open->op_truncate, &open->op_created); 229 &open->op_truncate, &open->op_created);
226 230
@@ -234,30 +238,29 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
234 FATTR4_WORD1_TIME_MODIFY); 238 FATTR4_WORD1_TIME_MODIFY);
235 } else { 239 } else {
236 status = nfsd_lookup(rqstp, current_fh, 240 status = nfsd_lookup(rqstp, current_fh,
237 open->op_fname.data, open->op_fname.len, &resfh); 241 open->op_fname.data, open->op_fname.len, resfh);
238 fh_unlock(current_fh); 242 fh_unlock(current_fh);
239 if (status) 243 if (status)
240 goto out; 244 goto out;
241 status = nfsd_check_obj_isreg(&resfh); 245 status = nfsd_check_obj_isreg(resfh);
242 } 246 }
243 if (status) 247 if (status)
244 goto out; 248 goto out;
245 249
246 if (is_create_with_attrs(open) && open->op_acl != NULL) 250 if (is_create_with_attrs(open) && open->op_acl != NULL)
247 do_set_nfs4_acl(rqstp, &resfh, open->op_acl, open->op_bmval); 251 do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
248
249 set_change_info(&open->op_cinfo, current_fh);
250 fh_dup2(current_fh, &resfh);
251 252
252 /* set reply cache */ 253 /* set reply cache */
253 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 254 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
254 &resfh.fh_handle); 255 &resfh->fh_handle);
255 if (!open->op_created) 256 if (!open->op_created)
256 status = do_open_permission(rqstp, current_fh, open, 257 status = do_open_permission(rqstp, resfh, open,
257 NFSD_MAY_NOP); 258 NFSD_MAY_NOP);
258 259 set_change_info(&open->op_cinfo, current_fh);
260 fh_dup2(current_fh, resfh);
259out: 261out:
260 fh_put(&resfh); 262 fh_put(resfh);
263 kfree(resfh);
261 return status; 264 return status;
262} 265}
263 266
@@ -310,9 +313,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
310 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 313 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
311 return nfserr_inval; 314 return nfserr_inval;
312 315
313 /* We don't yet support WANT bits: */
314 open->op_share_access &= NFS4_SHARE_ACCESS_MASK;
315
316 open->op_created = 0; 316 open->op_created = 0;
317 /* 317 /*
318 * RFC5661 18.51.3 318 * RFC5661 18.51.3
@@ -452,6 +452,10 @@ nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
452 return nfserr_restorefh; 452 return nfserr_restorefh;
453 453
454 fh_dup2(&cstate->current_fh, &cstate->save_fh); 454 fh_dup2(&cstate->current_fh, &cstate->save_fh);
455 if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) {
456 memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
457 SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
458 }
455 return nfs_ok; 459 return nfs_ok;
456} 460}
457 461
@@ -463,6 +467,10 @@ nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
463 return nfserr_nofilehandle; 467 return nfserr_nofilehandle;
464 468
465 fh_dup2(&cstate->save_fh, &cstate->current_fh); 469 fh_dup2(&cstate->save_fh, &cstate->current_fh);
470 if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) {
471 memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t));
472 SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG);
473 }
466 return nfs_ok; 474 return nfs_ok;
467} 475}
468 476
@@ -481,14 +489,20 @@ nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
481 &access->ac_supported); 489 &access->ac_supported);
482} 490}
483 491
492static void gen_boot_verifier(nfs4_verifier *verifier)
493{
494 __be32 verf[2];
495
496 verf[0] = (__be32)nfssvc_boot.tv_sec;
497 verf[1] = (__be32)nfssvc_boot.tv_usec;
498 memcpy(verifier->data, verf, sizeof(verifier->data));
499}
500
484static __be32 501static __be32
485nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 502nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
486 struct nfsd4_commit *commit) 503 struct nfsd4_commit *commit)
487{ 504{
488 u32 *p = (u32 *)commit->co_verf.data; 505 gen_boot_verifier(&commit->co_verf);
489 *p++ = nfssvc_boot.tv_sec;
490 *p++ = nfssvc_boot.tv_usec;
491
492 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 506 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
493 commit->co_count); 507 commit->co_count);
494} 508}
@@ -865,7 +879,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
865{ 879{
866 stateid_t *stateid = &write->wr_stateid; 880 stateid_t *stateid = &write->wr_stateid;
867 struct file *filp = NULL; 881 struct file *filp = NULL;
868 u32 *p;
869 __be32 status = nfs_ok; 882 __be32 status = nfs_ok;
870 unsigned long cnt; 883 unsigned long cnt;
871 884
@@ -887,9 +900,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
887 900
888 cnt = write->wr_buflen; 901 cnt = write->wr_buflen;
889 write->wr_how_written = write->wr_stable_how; 902 write->wr_how_written = write->wr_stable_how;
890 p = (u32 *)write->wr_verifier.data; 903 gen_boot_verifier(&write->wr_verifier);
891 *p++ = nfssvc_boot.tv_sec;
892 *p++ = nfssvc_boot.tv_usec;
893 904
894 status = nfsd_write(rqstp, &cstate->current_fh, filp, 905 status = nfsd_write(rqstp, &cstate->current_fh, filp,
895 write->wr_offset, rqstp->rq_vec, write->wr_vlen, 906 write->wr_offset, rqstp->rq_vec, write->wr_vlen,
@@ -1000,6 +1011,8 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
1000typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1011typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
1001 void *); 1012 void *);
1002typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); 1013typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
1014typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *);
1015typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *);
1003 1016
1004enum nfsd4_op_flags { 1017enum nfsd4_op_flags {
1005 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 1018 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
@@ -1025,6 +1038,10 @@ enum nfsd4_op_flags {
1025 * the v4.0 case). 1038 * the v4.0 case).
1026 */ 1039 */
1027 OP_CACHEME = 1 << 6, 1040 OP_CACHEME = 1 << 6,
1041 /*
1042 * These are ops which clear current state id.
1043 */
1044 OP_CLEAR_STATEID = 1 << 7,
1028}; 1045};
1029 1046
1030struct nfsd4_operation { 1047struct nfsd4_operation {
@@ -1033,11 +1050,15 @@ struct nfsd4_operation {
1033 char *op_name; 1050 char *op_name;
1034 /* Try to get response size before operation */ 1051 /* Try to get response size before operation */
1035 nfsd4op_rsize op_rsize_bop; 1052 nfsd4op_rsize op_rsize_bop;
1053 stateid_setter op_get_currentstateid;
1054 stateid_getter op_set_currentstateid;
1036}; 1055};
1037 1056
1038static struct nfsd4_operation nfsd4_ops[]; 1057static struct nfsd4_operation nfsd4_ops[];
1039 1058
1059#ifdef NFSD_DEBUG
1040static const char *nfsd4_op_name(unsigned opnum); 1060static const char *nfsd4_op_name(unsigned opnum);
1061#endif
1041 1062
1042/* 1063/*
1043 * Enforce NFSv4.1 COMPOUND ordering rules: 1064 * Enforce NFSv4.1 COMPOUND ordering rules:
@@ -1215,13 +1236,23 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1215 if (op->status) 1236 if (op->status)
1216 goto encode_op; 1237 goto encode_op;
1217 1238
1218 if (opdesc->op_func) 1239 if (opdesc->op_func) {
1240 if (opdesc->op_get_currentstateid)
1241 opdesc->op_get_currentstateid(cstate, &op->u);
1219 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1242 op->status = opdesc->op_func(rqstp, cstate, &op->u);
1220 else 1243 } else
1221 BUG_ON(op->status == nfs_ok); 1244 BUG_ON(op->status == nfs_ok);
1222 1245
1223 if (!op->status && need_wrongsec_check(rqstp)) 1246 if (!op->status) {
1224 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); 1247 if (opdesc->op_set_currentstateid)
1248 opdesc->op_set_currentstateid(cstate, &op->u);
1249
1250 if (opdesc->op_flags & OP_CLEAR_STATEID)
1251 clear_current_stateid(cstate);
1252
1253 if (need_wrongsec_check(rqstp))
1254 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp);
1255 }
1225 1256
1226encode_op: 1257encode_op:
1227 /* Only from SEQUENCE */ 1258 /* Only from SEQUENCE */
@@ -1413,6 +1444,8 @@ static struct nfsd4_operation nfsd4_ops[] = {
1413 .op_flags = OP_MODIFIES_SOMETHING, 1444 .op_flags = OP_MODIFIES_SOMETHING,
1414 .op_name = "OP_CLOSE", 1445 .op_name = "OP_CLOSE",
1415 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1446 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1447 .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid,
1448 .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid,
1416 }, 1449 },
1417 [OP_COMMIT] = { 1450 [OP_COMMIT] = {
1418 .op_func = (nfsd4op_func)nfsd4_commit, 1451 .op_func = (nfsd4op_func)nfsd4_commit,
@@ -1422,7 +1455,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1422 }, 1455 },
1423 [OP_CREATE] = { 1456 [OP_CREATE] = {
1424 .op_func = (nfsd4op_func)nfsd4_create, 1457 .op_func = (nfsd4op_func)nfsd4_create,
1425 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1458 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID,
1426 .op_name = "OP_CREATE", 1459 .op_name = "OP_CREATE",
1427 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize, 1460 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize,
1428 }, 1461 },
@@ -1431,6 +1464,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1431 .op_flags = OP_MODIFIES_SOMETHING, 1464 .op_flags = OP_MODIFIES_SOMETHING,
1432 .op_name = "OP_DELEGRETURN", 1465 .op_name = "OP_DELEGRETURN",
1433 .op_rsize_bop = nfsd4_only_status_rsize, 1466 .op_rsize_bop = nfsd4_only_status_rsize,
1467 .op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid,
1434 }, 1468 },
1435 [OP_GETATTR] = { 1469 [OP_GETATTR] = {
1436 .op_func = (nfsd4op_func)nfsd4_getattr, 1470 .op_func = (nfsd4op_func)nfsd4_getattr,
@@ -1453,6 +1487,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1453 .op_flags = OP_MODIFIES_SOMETHING, 1487 .op_flags = OP_MODIFIES_SOMETHING,
1454 .op_name = "OP_LOCK", 1488 .op_name = "OP_LOCK",
1455 .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, 1489 .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
1490 .op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid,
1456 }, 1491 },
1457 [OP_LOCKT] = { 1492 [OP_LOCKT] = {
1458 .op_func = (nfsd4op_func)nfsd4_lockt, 1493 .op_func = (nfsd4op_func)nfsd4_lockt,
@@ -1463,15 +1498,16 @@ static struct nfsd4_operation nfsd4_ops[] = {
1463 .op_flags = OP_MODIFIES_SOMETHING, 1498 .op_flags = OP_MODIFIES_SOMETHING,
1464 .op_name = "OP_LOCKU", 1499 .op_name = "OP_LOCKU",
1465 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1500 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1501 .op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid,
1466 }, 1502 },
1467 [OP_LOOKUP] = { 1503 [OP_LOOKUP] = {
1468 .op_func = (nfsd4op_func)nfsd4_lookup, 1504 .op_func = (nfsd4op_func)nfsd4_lookup,
1469 .op_flags = OP_HANDLES_WRONGSEC, 1505 .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
1470 .op_name = "OP_LOOKUP", 1506 .op_name = "OP_LOOKUP",
1471 }, 1507 },
1472 [OP_LOOKUPP] = { 1508 [OP_LOOKUPP] = {
1473 .op_func = (nfsd4op_func)nfsd4_lookupp, 1509 .op_func = (nfsd4op_func)nfsd4_lookupp,
1474 .op_flags = OP_HANDLES_WRONGSEC, 1510 .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
1475 .op_name = "OP_LOOKUPP", 1511 .op_name = "OP_LOOKUPP",
1476 }, 1512 },
1477 [OP_NVERIFY] = { 1513 [OP_NVERIFY] = {
@@ -1483,6 +1519,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1483 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, 1519 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
1484 .op_name = "OP_OPEN", 1520 .op_name = "OP_OPEN",
1485 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, 1521 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize,
1522 .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid,
1486 }, 1523 },
1487 [OP_OPEN_CONFIRM] = { 1524 [OP_OPEN_CONFIRM] = {
1488 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1525 .op_func = (nfsd4op_func)nfsd4_open_confirm,
@@ -1495,25 +1532,30 @@ static struct nfsd4_operation nfsd4_ops[] = {
1495 .op_flags = OP_MODIFIES_SOMETHING, 1532 .op_flags = OP_MODIFIES_SOMETHING,
1496 .op_name = "OP_OPEN_DOWNGRADE", 1533 .op_name = "OP_OPEN_DOWNGRADE",
1497 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1534 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1535 .op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid,
1536 .op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid,
1498 }, 1537 },
1499 [OP_PUTFH] = { 1538 [OP_PUTFH] = {
1500 .op_func = (nfsd4op_func)nfsd4_putfh, 1539 .op_func = (nfsd4op_func)nfsd4_putfh,
1501 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1540 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1502 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1541 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
1542 | OP_CLEAR_STATEID,
1503 .op_name = "OP_PUTFH", 1543 .op_name = "OP_PUTFH",
1504 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1544 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1505 }, 1545 },
1506 [OP_PUTPUBFH] = { 1546 [OP_PUTPUBFH] = {
1507 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1547 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1508 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1548 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1509 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1549 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
1550 | OP_CLEAR_STATEID,
1510 .op_name = "OP_PUTPUBFH", 1551 .op_name = "OP_PUTPUBFH",
1511 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1552 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1512 }, 1553 },
1513 [OP_PUTROOTFH] = { 1554 [OP_PUTROOTFH] = {
1514 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1555 .op_func = (nfsd4op_func)nfsd4_putrootfh,
1515 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1556 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
1516 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1557 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
1558 | OP_CLEAR_STATEID,
1517 .op_name = "OP_PUTROOTFH", 1559 .op_name = "OP_PUTROOTFH",
1518 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1560 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
1519 }, 1561 },
@@ -1522,6 +1564,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1522 .op_flags = OP_MODIFIES_SOMETHING, 1564 .op_flags = OP_MODIFIES_SOMETHING,
1523 .op_name = "OP_READ", 1565 .op_name = "OP_READ",
1524 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, 1566 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize,
1567 .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid,
1525 }, 1568 },
1526 [OP_READDIR] = { 1569 [OP_READDIR] = {
1527 .op_func = (nfsd4op_func)nfsd4_readdir, 1570 .op_func = (nfsd4op_func)nfsd4_readdir,
@@ -1576,6 +1619,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1576 .op_name = "OP_SETATTR", 1619 .op_name = "OP_SETATTR",
1577 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1620 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1578 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize, 1621 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize,
1622 .op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid,
1579 }, 1623 },
1580 [OP_SETCLIENTID] = { 1624 [OP_SETCLIENTID] = {
1581 .op_func = (nfsd4op_func)nfsd4_setclientid, 1625 .op_func = (nfsd4op_func)nfsd4_setclientid,
@@ -1600,6 +1644,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
1600 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1644 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1601 .op_name = "OP_WRITE", 1645 .op_name = "OP_WRITE",
1602 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, 1646 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
1647 .op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid,
1603 }, 1648 },
1604 [OP_RELEASE_LOCKOWNER] = { 1649 [OP_RELEASE_LOCKOWNER] = {
1605 .op_func = (nfsd4op_func)nfsd4_release_lockowner, 1650 .op_func = (nfsd4op_func)nfsd4_release_lockowner,
@@ -1674,12 +1719,14 @@ static struct nfsd4_operation nfsd4_ops[] = {
1674 }, 1719 },
1675}; 1720};
1676 1721
1722#ifdef NFSD_DEBUG
1677static const char *nfsd4_op_name(unsigned opnum) 1723static const char *nfsd4_op_name(unsigned opnum)
1678{ 1724{
1679 if (opnum < ARRAY_SIZE(nfsd4_ops)) 1725 if (opnum < ARRAY_SIZE(nfsd4_ops))
1680 return nfsd4_ops[opnum].op_name; 1726 return nfsd4_ops[opnum].op_name;
1681 return "unknown_operation"; 1727 return "unknown_operation";
1682} 1728}
1729#endif
1683 1730
1684#define nfsd4_voidres nfsd4_voidargs 1731#define nfsd4_voidres nfsd4_voidargs
1685struct nfsd4_voidargs { int dummy; }; 1732struct nfsd4_voidargs { int dummy; };
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c5cddd659429..a0a2b535b0e0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -58,11 +58,15 @@ static const stateid_t one_stateid = {
58static const stateid_t zero_stateid = { 58static const stateid_t zero_stateid = {
59 /* all fields zero */ 59 /* all fields zero */
60}; 60};
61static const stateid_t currentstateid = {
62 .si_generation = 1,
63};
61 64
62static u64 current_sessionid = 1; 65static u64 current_sessionid = 1;
63 66
64#define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t))) 67#define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t)))
65#define ONE_STATEID(stateid) (!memcmp((stateid), &one_stateid, sizeof(stateid_t))) 68#define ONE_STATEID(stateid) (!memcmp((stateid), &one_stateid, sizeof(stateid_t)))
69#define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t)))
66 70
67/* forward declarations */ 71/* forward declarations */
68static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner); 72static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
@@ -91,6 +95,19 @@ nfs4_lock_state(void)
91 mutex_lock(&client_mutex); 95 mutex_lock(&client_mutex);
92} 96}
93 97
98static void free_session(struct kref *);
99
100/* Must be called under the client_lock */
101static void nfsd4_put_session_locked(struct nfsd4_session *ses)
102{
103 kref_put(&ses->se_ref, free_session);
104}
105
106static void nfsd4_get_session(struct nfsd4_session *ses)
107{
108 kref_get(&ses->se_ref);
109}
110
94void 111void
95nfs4_unlock_state(void) 112nfs4_unlock_state(void)
96{ 113{
@@ -605,12 +622,20 @@ hash_sessionid(struct nfs4_sessionid *sessionid)
605 return sid->sequence % SESSION_HASH_SIZE; 622 return sid->sequence % SESSION_HASH_SIZE;
606} 623}
607 624
625#ifdef NFSD_DEBUG
608static inline void 626static inline void
609dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid) 627dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
610{ 628{
611 u32 *ptr = (u32 *)(&sessionid->data[0]); 629 u32 *ptr = (u32 *)(&sessionid->data[0]);
612 dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]); 630 dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]);
613} 631}
632#else
633static inline void
634dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
635{
636}
637#endif
638
614 639
615static void 640static void
616gen_sessionid(struct nfsd4_session *ses) 641gen_sessionid(struct nfsd4_session *ses)
@@ -832,11 +857,12 @@ static void nfsd4_del_conns(struct nfsd4_session *s)
832 spin_unlock(&clp->cl_lock); 857 spin_unlock(&clp->cl_lock);
833} 858}
834 859
835void free_session(struct kref *kref) 860static void free_session(struct kref *kref)
836{ 861{
837 struct nfsd4_session *ses; 862 struct nfsd4_session *ses;
838 int mem; 863 int mem;
839 864
865 BUG_ON(!spin_is_locked(&client_lock));
840 ses = container_of(kref, struct nfsd4_session, se_ref); 866 ses = container_of(kref, struct nfsd4_session, se_ref);
841 nfsd4_del_conns(ses); 867 nfsd4_del_conns(ses);
842 spin_lock(&nfsd_drc_lock); 868 spin_lock(&nfsd_drc_lock);
@@ -847,6 +873,13 @@ void free_session(struct kref *kref)
847 kfree(ses); 873 kfree(ses);
848} 874}
849 875
876void nfsd4_put_session(struct nfsd4_session *ses)
877{
878 spin_lock(&client_lock);
879 nfsd4_put_session_locked(ses);
880 spin_unlock(&client_lock);
881}
882
850static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses) 883static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses)
851{ 884{
852 struct nfsd4_session *new; 885 struct nfsd4_session *new;
@@ -894,7 +927,9 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
894 status = nfsd4_new_conn_from_crses(rqstp, new); 927 status = nfsd4_new_conn_from_crses(rqstp, new);
895 /* whoops: benny points out, status is ignored! (err, or bogus) */ 928 /* whoops: benny points out, status is ignored! (err, or bogus) */
896 if (status) { 929 if (status) {
930 spin_lock(&client_lock);
897 free_session(&new->se_ref); 931 free_session(&new->se_ref);
932 spin_unlock(&client_lock);
898 return NULL; 933 return NULL;
899 } 934 }
900 if (cses->flags & SESSION4_BACK_CHAN) { 935 if (cses->flags & SESSION4_BACK_CHAN) {
@@ -1006,12 +1041,13 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1006static inline void 1041static inline void
1007free_client(struct nfs4_client *clp) 1042free_client(struct nfs4_client *clp)
1008{ 1043{
1044 BUG_ON(!spin_is_locked(&client_lock));
1009 while (!list_empty(&clp->cl_sessions)) { 1045 while (!list_empty(&clp->cl_sessions)) {
1010 struct nfsd4_session *ses; 1046 struct nfsd4_session *ses;
1011 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session, 1047 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
1012 se_perclnt); 1048 se_perclnt);
1013 list_del(&ses->se_perclnt); 1049 list_del(&ses->se_perclnt);
1014 nfsd4_put_session(ses); 1050 nfsd4_put_session_locked(ses);
1015 } 1051 }
1016 if (clp->cl_cred.cr_group_info) 1052 if (clp->cl_cred.cr_group_info)
1017 put_group_info(clp->cl_cred.cr_group_info); 1053 put_group_info(clp->cl_cred.cr_group_info);
@@ -1138,12 +1174,12 @@ static void gen_clid(struct nfs4_client *clp)
1138 1174
1139static void gen_confirm(struct nfs4_client *clp) 1175static void gen_confirm(struct nfs4_client *clp)
1140{ 1176{
1177 __be32 verf[2];
1141 static u32 i; 1178 static u32 i;
1142 u32 *p;
1143 1179
1144 p = (u32 *)clp->cl_confirm.data; 1180 verf[0] = (__be32)get_seconds();
1145 *p++ = get_seconds(); 1181 verf[1] = (__be32)i++;
1146 *p++ = i++; 1182 memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
1147} 1183}
1148 1184
1149static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t) 1185static struct nfs4_stid *find_stateid(struct nfs4_client *cl, stateid_t *t)
@@ -1180,7 +1216,9 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1180 if (princ) { 1216 if (princ) {
1181 clp->cl_principal = kstrdup(princ, GFP_KERNEL); 1217 clp->cl_principal = kstrdup(princ, GFP_KERNEL);
1182 if (clp->cl_principal == NULL) { 1218 if (clp->cl_principal == NULL) {
1219 spin_lock(&client_lock);
1183 free_client(clp); 1220 free_client(clp);
1221 spin_unlock(&client_lock);
1184 return NULL; 1222 return NULL;
1185 } 1223 }
1186 } 1224 }
@@ -1347,6 +1385,7 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
1347 slot->sl_opcnt = resp->opcnt; 1385 slot->sl_opcnt = resp->opcnt;
1348 slot->sl_status = resp->cstate.status; 1386 slot->sl_status = resp->cstate.status;
1349 1387
1388 slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
1350 if (nfsd4_not_cached(resp)) { 1389 if (nfsd4_not_cached(resp)) {
1351 slot->sl_datalen = 0; 1390 slot->sl_datalen = 0;
1352 return; 1391 return;
@@ -1374,15 +1413,12 @@ nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
1374 struct nfsd4_op *op; 1413 struct nfsd4_op *op;
1375 struct nfsd4_slot *slot = resp->cstate.slot; 1414 struct nfsd4_slot *slot = resp->cstate.slot;
1376 1415
1377 dprintk("--> %s resp->opcnt %d cachethis %u \n", __func__,
1378 resp->opcnt, resp->cstate.slot->sl_cachethis);
1379
1380 /* Encode the replayed sequence operation */ 1416 /* Encode the replayed sequence operation */
1381 op = &args->ops[resp->opcnt - 1]; 1417 op = &args->ops[resp->opcnt - 1];
1382 nfsd4_encode_operation(resp, op); 1418 nfsd4_encode_operation(resp, op);
1383 1419
1384 /* Return nfserr_retry_uncached_rep in next operation. */ 1420 /* Return nfserr_retry_uncached_rep in next operation. */
1385 if (args->opcnt > 1 && slot->sl_cachethis == 0) { 1421 if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
1386 op = &args->ops[resp->opcnt++]; 1422 op = &args->ops[resp->opcnt++];
1387 op->status = nfserr_retry_uncached_rep; 1423 op->status = nfserr_retry_uncached_rep;
1388 nfsd4_encode_operation(resp, op); 1424 nfsd4_encode_operation(resp, op);
@@ -1575,16 +1611,11 @@ check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
1575 else 1611 else
1576 return nfserr_seq_misordered; 1612 return nfserr_seq_misordered;
1577 } 1613 }
1578 /* Normal */ 1614 /* Note unsigned 32-bit arithmetic handles wraparound: */
1579 if (likely(seqid == slot_seqid + 1)) 1615 if (likely(seqid == slot_seqid + 1))
1580 return nfs_ok; 1616 return nfs_ok;
1581 /* Replay */
1582 if (seqid == slot_seqid) 1617 if (seqid == slot_seqid)
1583 return nfserr_replay_cache; 1618 return nfserr_replay_cache;
1584 /* Wraparound */
1585 if (seqid == 1 && (slot_seqid + 1) == 0)
1586 return nfs_ok;
1587 /* Misordered replay or misordered new request */
1588 return nfserr_seq_misordered; 1619 return nfserr_seq_misordered;
1589} 1620}
1590 1621
@@ -1815,9 +1846,10 @@ nfsd4_destroy_session(struct svc_rqst *r,
1815 nfsd4_probe_callback_sync(ses->se_client); 1846 nfsd4_probe_callback_sync(ses->se_client);
1816 nfs4_unlock_state(); 1847 nfs4_unlock_state();
1817 1848
1849 spin_lock(&client_lock);
1818 nfsd4_del_conns(ses); 1850 nfsd4_del_conns(ses);
1819 1851 nfsd4_put_session_locked(ses);
1820 nfsd4_put_session(ses); 1852 spin_unlock(&client_lock);
1821 status = nfs_ok; 1853 status = nfs_ok;
1822out: 1854out:
1823 dprintk("%s returns %d\n", __func__, ntohl(status)); 1855 dprintk("%s returns %d\n", __func__, ntohl(status));
@@ -1921,8 +1953,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1921 * sr_highest_slotid and the sr_target_slot id to maxslots */ 1953 * sr_highest_slotid and the sr_target_slot id to maxslots */
1922 seq->maxslots = session->se_fchannel.maxreqs; 1954 seq->maxslots = session->se_fchannel.maxreqs;
1923 1955
1924 status = check_slot_seqid(seq->seqid, slot->sl_seqid, slot->sl_inuse); 1956 status = check_slot_seqid(seq->seqid, slot->sl_seqid,
1957 slot->sl_flags & NFSD4_SLOT_INUSE);
1925 if (status == nfserr_replay_cache) { 1958 if (status == nfserr_replay_cache) {
1959 status = nfserr_seq_misordered;
1960 if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
1961 goto out;
1926 cstate->slot = slot; 1962 cstate->slot = slot;
1927 cstate->session = session; 1963 cstate->session = session;
1928 /* Return the cached reply status and set cstate->status 1964 /* Return the cached reply status and set cstate->status
@@ -1938,9 +1974,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1938 conn = NULL; 1974 conn = NULL;
1939 1975
1940 /* Success! bump slot seqid */ 1976 /* Success! bump slot seqid */
1941 slot->sl_inuse = true;
1942 slot->sl_seqid = seq->seqid; 1977 slot->sl_seqid = seq->seqid;
1943 slot->sl_cachethis = seq->cachethis; 1978 slot->sl_flags |= NFSD4_SLOT_INUSE;
1979 if (seq->cachethis)
1980 slot->sl_flags |= NFSD4_SLOT_CACHETHIS;
1981 else
1982 slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS;
1944 1983
1945 cstate->slot = slot; 1984 cstate->slot = slot;
1946 cstate->session = session; 1985 cstate->session = session;
@@ -2633,8 +2672,6 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
2633 2672
2634static int share_access_to_flags(u32 share_access) 2673static int share_access_to_flags(u32 share_access)
2635{ 2674{
2636 share_access &= ~NFS4_SHARE_WANT_MASK;
2637
2638 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE; 2675 return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
2639} 2676}
2640 2677
@@ -2776,10 +2813,15 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2776 2813
2777 2814
2778static void 2815static void
2779nfs4_set_claim_prev(struct nfsd4_open *open) 2816nfs4_set_claim_prev(struct nfsd4_open *open, bool has_session)
2780{ 2817{
2781 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 2818 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2782 open->op_openowner->oo_owner.so_client->cl_firststate = 1; 2819 /*
2820 * On a 4.1+ client, we don't create a state record for a client
2821 * until it performs RECLAIM_COMPLETE:
2822 */
2823 if (!has_session)
2824 open->op_openowner->oo_owner.so_client->cl_firststate = 1;
2783} 2825}
2784 2826
2785/* Should we give out recallable state?: */ 2827/* Should we give out recallable state?: */
@@ -2855,6 +2897,27 @@ static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag)
2855 return 0; 2897 return 0;
2856} 2898}
2857 2899
2900static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
2901{
2902 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
2903 if (status == -EAGAIN)
2904 open->op_why_no_deleg = WND4_CONTENTION;
2905 else {
2906 open->op_why_no_deleg = WND4_RESOURCE;
2907 switch (open->op_deleg_want) {
2908 case NFS4_SHARE_WANT_READ_DELEG:
2909 case NFS4_SHARE_WANT_WRITE_DELEG:
2910 case NFS4_SHARE_WANT_ANY_DELEG:
2911 break;
2912 case NFS4_SHARE_WANT_CANCEL:
2913 open->op_why_no_deleg = WND4_CANCELLED;
2914 break;
2915 case NFS4_SHARE_WANT_NO_DELEG:
2916 BUG(); /* not supposed to get here */
2917 }
2918 }
2919}
2920
2858/* 2921/*
2859 * Attempt to hand out a delegation. 2922 * Attempt to hand out a delegation.
2860 */ 2923 */
@@ -2864,7 +2927,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_
2864 struct nfs4_delegation *dp; 2927 struct nfs4_delegation *dp;
2865 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); 2928 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
2866 int cb_up; 2929 int cb_up;
2867 int status, flag = 0; 2930 int status = 0, flag = 0;
2868 2931
2869 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); 2932 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
2870 flag = NFS4_OPEN_DELEGATE_NONE; 2933 flag = NFS4_OPEN_DELEGATE_NONE;
@@ -2905,11 +2968,16 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_
2905 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", 2968 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
2906 STATEID_VAL(&dp->dl_stid.sc_stateid)); 2969 STATEID_VAL(&dp->dl_stid.sc_stateid));
2907out: 2970out:
2908 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
2909 && flag == NFS4_OPEN_DELEGATE_NONE
2910 && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
2911 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
2912 open->op_delegate_type = flag; 2971 open->op_delegate_type = flag;
2972 if (flag == NFS4_OPEN_DELEGATE_NONE) {
2973 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
2974 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
2975 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
2976
2977 /* 4.1 client asking for a delegation? */
2978 if (open->op_deleg_want)
2979 nfsd4_open_deleg_none_ext(open, status);
2980 }
2913 return; 2981 return;
2914out_free: 2982out_free:
2915 nfs4_put_delegation(dp); 2983 nfs4_put_delegation(dp);
@@ -2918,6 +2986,24 @@ out_no_deleg:
2918 goto out; 2986 goto out;
2919} 2987}
2920 2988
2989static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
2990 struct nfs4_delegation *dp)
2991{
2992 if (open->op_deleg_want == NFS4_SHARE_WANT_READ_DELEG &&
2993 dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
2994 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
2995 open->op_why_no_deleg = WND4_NOT_SUPP_DOWNGRADE;
2996 } else if (open->op_deleg_want == NFS4_SHARE_WANT_WRITE_DELEG &&
2997 dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
2998 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
2999 open->op_why_no_deleg = WND4_NOT_SUPP_UPGRADE;
3000 }
3001 /* Otherwise the client must be confused wanting a delegation
3002 * it already has, therefore we don't return
3003 * NFS4_OPEN_DELEGATE_NONE_EXT and reason.
3004 */
3005}
3006
2921/* 3007/*
2922 * called with nfs4_lock_state() held. 3008 * called with nfs4_lock_state() held.
2923 */ 3009 */
@@ -2979,24 +3065,36 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2979 update_stateid(&stp->st_stid.sc_stateid); 3065 update_stateid(&stp->st_stid.sc_stateid);
2980 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3066 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
2981 3067
2982 if (nfsd4_has_session(&resp->cstate)) 3068 if (nfsd4_has_session(&resp->cstate)) {
2983 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 3069 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
2984 3070
3071 if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
3072 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
3073 open->op_why_no_deleg = WND4_NOT_WANTED;
3074 goto nodeleg;
3075 }
3076 }
3077
2985 /* 3078 /*
2986 * Attempt to hand out a delegation. No error return, because the 3079 * Attempt to hand out a delegation. No error return, because the
2987 * OPEN succeeds even if we fail. 3080 * OPEN succeeds even if we fail.
2988 */ 3081 */
2989 nfs4_open_delegation(current_fh, open, stp); 3082 nfs4_open_delegation(current_fh, open, stp);
2990 3083nodeleg:
2991 status = nfs_ok; 3084 status = nfs_ok;
2992 3085
2993 dprintk("%s: stateid=" STATEID_FMT "\n", __func__, 3086 dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
2994 STATEID_VAL(&stp->st_stid.sc_stateid)); 3087 STATEID_VAL(&stp->st_stid.sc_stateid));
2995out: 3088out:
3089 /* 4.1 client trying to upgrade/downgrade delegation? */
3090 if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
3091 open->op_deleg_want)
3092 nfsd4_deleg_xgrade_none_ext(open, dp);
3093
2996 if (fp) 3094 if (fp)
2997 put_nfs4_file(fp); 3095 put_nfs4_file(fp);
2998 if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 3096 if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
2999 nfs4_set_claim_prev(open); 3097 nfs4_set_claim_prev(open, nfsd4_has_session(&resp->cstate));
3000 /* 3098 /*
3001 * To finish the open response, we just need to set the rflags. 3099 * To finish the open response, we just need to set the rflags.
3002 */ 3100 */
@@ -3400,7 +3498,14 @@ __be32
3400nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3498nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3401 struct nfsd4_test_stateid *test_stateid) 3499 struct nfsd4_test_stateid *test_stateid)
3402{ 3500{
3403 /* real work is done during encoding */ 3501 struct nfsd4_test_stateid_id *stateid;
3502 struct nfs4_client *cl = cstate->session->se_client;
3503
3504 nfs4_lock_state();
3505 list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
3506 stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid);
3507 nfs4_unlock_state();
3508
3404 return nfs_ok; 3509 return nfs_ok;
3405} 3510}
3406 3511
@@ -3596,7 +3701,9 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3596 cstate->current_fh.fh_dentry->d_name.name); 3701 cstate->current_fh.fh_dentry->d_name.name);
3597 3702
3598 /* We don't yet support WANT bits: */ 3703 /* We don't yet support WANT bits: */
3599 od->od_share_access &= NFS4_SHARE_ACCESS_MASK; 3704 if (od->od_deleg_want)
3705 dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
3706 od->od_deleg_want);
3600 3707
3601 nfs4_lock_state(); 3708 nfs4_lock_state();
3602 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid, 3709 status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
@@ -4353,7 +4460,9 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
4353 struct nfs4_client *clp; 4460 struct nfs4_client *clp;
4354 4461
4355 clp = find_confirmed_client_by_str(name, strhashval); 4462 clp = find_confirmed_client_by_str(name, strhashval);
4356 return clp ? 1 : 0; 4463 if (!clp)
4464 return 0;
4465 return clp->cl_firststate;
4357} 4466}
4358 4467
4359/* 4468/*
@@ -4613,21 +4722,26 @@ set_max_delegations(void)
4613 4722
4614/* initialization to perform when the nfsd service is started: */ 4723/* initialization to perform when the nfsd service is started: */
4615 4724
4616static int 4725int
4617__nfs4_state_start(void) 4726nfs4_state_start(void)
4618{ 4727{
4619 int ret; 4728 int ret;
4620 4729
4730 nfsd4_load_reboot_recovery_data();
4621 boot_time = get_seconds(); 4731 boot_time = get_seconds();
4622 locks_start_grace(&nfsd4_manager); 4732 locks_start_grace(&nfsd4_manager);
4623 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4733 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4624 nfsd4_grace); 4734 nfsd4_grace);
4625 ret = set_callback_cred(); 4735 ret = set_callback_cred();
4626 if (ret) 4736 if (ret) {
4627 return -ENOMEM; 4737 ret = -ENOMEM;
4738 goto out_recovery;
4739 }
4628 laundry_wq = create_singlethread_workqueue("nfsd4"); 4740 laundry_wq = create_singlethread_workqueue("nfsd4");
4629 if (laundry_wq == NULL) 4741 if (laundry_wq == NULL) {
4630 return -ENOMEM; 4742 ret = -ENOMEM;
4743 goto out_recovery;
4744 }
4631 ret = nfsd4_create_callback_queue(); 4745 ret = nfsd4_create_callback_queue();
4632 if (ret) 4746 if (ret)
4633 goto out_free_laundry; 4747 goto out_free_laundry;
@@ -4636,16 +4750,12 @@ __nfs4_state_start(void)
4636 return 0; 4750 return 0;
4637out_free_laundry: 4751out_free_laundry:
4638 destroy_workqueue(laundry_wq); 4752 destroy_workqueue(laundry_wq);
4753out_recovery:
4754 nfs4_release_reclaim();
4755 nfsd4_shutdown_recdir();
4639 return ret; 4756 return ret;
4640} 4757}
4641 4758
4642int
4643nfs4_state_start(void)
4644{
4645 nfsd4_load_reboot_recovery_data();
4646 return __nfs4_state_start();
4647}
4648
4649static void 4759static void
4650__nfs4_state_shutdown(void) 4760__nfs4_state_shutdown(void)
4651{ 4761{
@@ -4691,3 +4801,104 @@ nfs4_state_shutdown(void)
4691 nfs4_unlock_state(); 4801 nfs4_unlock_state();
4692 nfsd4_destroy_callback_queue(); 4802 nfsd4_destroy_callback_queue();
4693} 4803}
4804
4805static void
4806get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
4807{
4808 if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
4809 memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
4810}
4811
4812static void
4813put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
4814{
4815 if (cstate->minorversion) {
4816 memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t));
4817 SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
4818 }
4819}
4820
4821void
4822clear_current_stateid(struct nfsd4_compound_state *cstate)
4823{
4824 CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
4825}
4826
4827/*
4828 * functions to set current state id
4829 */
4830void
4831nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
4832{
4833 put_stateid(cstate, &odp->od_stateid);
4834}
4835
4836void
4837nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
4838{
4839 put_stateid(cstate, &open->op_stateid);
4840}
4841
4842void
4843nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
4844{
4845 put_stateid(cstate, &close->cl_stateid);
4846}
4847
4848void
4849nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lock)
4850{
4851 put_stateid(cstate, &lock->lk_resp_stateid);
4852}
4853
4854/*
4855 * functions to consume current state id
4856 */
4857
4858void
4859nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
4860{
4861 get_stateid(cstate, &odp->od_stateid);
4862}
4863
4864void
4865nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, struct nfsd4_delegreturn *drp)
4866{
4867 get_stateid(cstate, &drp->dr_stateid);
4868}
4869
4870void
4871nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, struct nfsd4_free_stateid *fsp)
4872{
4873 get_stateid(cstate, &fsp->fr_stateid);
4874}
4875
4876void
4877nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr)
4878{
4879 get_stateid(cstate, &setattr->sa_stateid);
4880}
4881
4882void
4883nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
4884{
4885 get_stateid(cstate, &close->cl_stateid);
4886}
4887
4888void
4889nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku)
4890{
4891 get_stateid(cstate, &locku->lu_stateid);
4892}
4893
4894void
4895nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, struct nfsd4_read *read)
4896{
4897 get_stateid(cstate, &read->rd_stateid);
4898}
4899
4900void
4901nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, struct nfsd4_write *write)
4902{
4903 get_stateid(cstate, &write->wr_stateid);
4904}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 0ec5a1b9700e..bcd8904ab1e3 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -133,22 +133,6 @@ xdr_error: \
133 } \ 133 } \
134} while (0) 134} while (0)
135 135
136static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
137{
138 savep->p = argp->p;
139 savep->end = argp->end;
140 savep->pagelen = argp->pagelen;
141 savep->pagelist = argp->pagelist;
142}
143
144static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
145{
146 argp->p = savep->p;
147 argp->end = savep->end;
148 argp->pagelen = savep->pagelen;
149 argp->pagelist = savep->pagelist;
150}
151
152static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) 136static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
153{ 137{
154 /* We want more bytes than seem to be available. 138 /* We want more bytes than seem to be available.
@@ -638,14 +622,18 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
638 DECODE_TAIL; 622 DECODE_TAIL;
639} 623}
640 624
641static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x) 625static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
642{ 626{
643 __be32 *p; 627 __be32 *p;
644 u32 w; 628 u32 w;
645 629
646 READ_BUF(4); 630 READ_BUF(4);
647 READ32(w); 631 READ32(w);
648 *x = w; 632 *share_access = w & NFS4_SHARE_ACCESS_MASK;
633 *deleg_want = w & NFS4_SHARE_WANT_MASK;
634 if (deleg_when)
635 *deleg_when = w & NFS4_SHARE_WHEN_MASK;
636
649 switch (w & NFS4_SHARE_ACCESS_MASK) { 637 switch (w & NFS4_SHARE_ACCESS_MASK) {
650 case NFS4_SHARE_ACCESS_READ: 638 case NFS4_SHARE_ACCESS_READ:
651 case NFS4_SHARE_ACCESS_WRITE: 639 case NFS4_SHARE_ACCESS_WRITE:
@@ -673,6 +661,9 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
673 w &= ~NFS4_SHARE_WANT_MASK; 661 w &= ~NFS4_SHARE_WANT_MASK;
674 if (!w) 662 if (!w)
675 return nfs_ok; 663 return nfs_ok;
664
665 if (!deleg_when) /* open_downgrade */
666 return nfserr_inval;
676 switch (w) { 667 switch (w) {
677 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL: 668 case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
678 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED: 669 case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
@@ -719,6 +710,7 @@ static __be32
719nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 710nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
720{ 711{
721 DECODE_HEAD; 712 DECODE_HEAD;
713 u32 dummy;
722 714
723 memset(open->op_bmval, 0, sizeof(open->op_bmval)); 715 memset(open->op_bmval, 0, sizeof(open->op_bmval));
724 open->op_iattr.ia_valid = 0; 716 open->op_iattr.ia_valid = 0;
@@ -727,7 +719,9 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
727 /* seqid, share_access, share_deny, clientid, ownerlen */ 719 /* seqid, share_access, share_deny, clientid, ownerlen */
728 READ_BUF(4); 720 READ_BUF(4);
729 READ32(open->op_seqid); 721 READ32(open->op_seqid);
730 status = nfsd4_decode_share_access(argp, &open->op_share_access); 722 /* decode, yet ignore deleg_when until supported */
723 status = nfsd4_decode_share_access(argp, &open->op_share_access,
724 &open->op_deleg_want, &dummy);
731 if (status) 725 if (status)
732 goto xdr_error; 726 goto xdr_error;
733 status = nfsd4_decode_share_deny(argp, &open->op_share_deny); 727 status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
@@ -755,14 +749,14 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
755 goto out; 749 goto out;
756 break; 750 break;
757 case NFS4_CREATE_EXCLUSIVE: 751 case NFS4_CREATE_EXCLUSIVE:
758 READ_BUF(8); 752 READ_BUF(NFS4_VERIFIER_SIZE);
759 COPYMEM(open->op_verf.data, 8); 753 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
760 break; 754 break;
761 case NFS4_CREATE_EXCLUSIVE4_1: 755 case NFS4_CREATE_EXCLUSIVE4_1:
762 if (argp->minorversion < 1) 756 if (argp->minorversion < 1)
763 goto xdr_error; 757 goto xdr_error;
764 READ_BUF(8); 758 READ_BUF(NFS4_VERIFIER_SIZE);
765 COPYMEM(open->op_verf.data, 8); 759 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
766 status = nfsd4_decode_fattr(argp, open->op_bmval, 760 status = nfsd4_decode_fattr(argp, open->op_bmval,
767 &open->op_iattr, &open->op_acl); 761 &open->op_iattr, &open->op_acl);
768 if (status) 762 if (status)
@@ -848,7 +842,8 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
848 return status; 842 return status;
849 READ_BUF(4); 843 READ_BUF(4);
850 READ32(open_down->od_seqid); 844 READ32(open_down->od_seqid);
851 status = nfsd4_decode_share_access(argp, &open_down->od_share_access); 845 status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
846 &open_down->od_deleg_want, NULL);
852 if (status) 847 if (status)
853 return status; 848 return status;
854 status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny); 849 status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
@@ -994,8 +989,8 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
994{ 989{
995 DECODE_HEAD; 990 DECODE_HEAD;
996 991
997 READ_BUF(8); 992 READ_BUF(NFS4_VERIFIER_SIZE);
998 COPYMEM(setclientid->se_verf.data, 8); 993 COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
999 994
1000 status = nfsd4_decode_opaque(argp, &setclientid->se_name); 995 status = nfsd4_decode_opaque(argp, &setclientid->se_name);
1001 if (status) 996 if (status)
@@ -1020,9 +1015,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
1020{ 1015{
1021 DECODE_HEAD; 1016 DECODE_HEAD;
1022 1017
1023 READ_BUF(8 + sizeof(nfs4_verifier)); 1018 READ_BUF(8 + NFS4_VERIFIER_SIZE);
1024 COPYMEM(&scd_c->sc_clientid, 8); 1019 COPYMEM(&scd_c->sc_clientid, 8);
1025 COPYMEM(&scd_c->sc_confirm, sizeof(nfs4_verifier)); 1020 COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
1026 1021
1027 DECODE_TAIL; 1022 DECODE_TAIL;
1028} 1023}
@@ -1385,26 +1380,29 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1385static __be32 1380static __be32
1386nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid) 1381nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1387{ 1382{
1388 unsigned int nbytes;
1389 stateid_t si;
1390 int i; 1383 int i;
1391 __be32 *p; 1384 __be32 *p, status;
1392 __be32 status; 1385 struct nfsd4_test_stateid_id *stateid;
1393 1386
1394 READ_BUF(4); 1387 READ_BUF(4);
1395 test_stateid->ts_num_ids = ntohl(*p++); 1388 test_stateid->ts_num_ids = ntohl(*p++);
1396 1389
1397 nbytes = test_stateid->ts_num_ids * sizeof(stateid_t); 1390 INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
1398 if (nbytes > (u32)((char *)argp->end - (char *)argp->p))
1399 goto xdr_error;
1400
1401 test_stateid->ts_saved_args = argp;
1402 save_buf(argp, &test_stateid->ts_savedp);
1403 1391
1404 for (i = 0; i < test_stateid->ts_num_ids; i++) { 1392 for (i = 0; i < test_stateid->ts_num_ids; i++) {
1405 status = nfsd4_decode_stateid(argp, &si); 1393 stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
1394 if (!stateid) {
1395 status = PTR_ERR(stateid);
1396 goto out;
1397 }
1398
1399 defer_free(argp, kfree, stateid);
1400 INIT_LIST_HEAD(&stateid->ts_id_list);
1401 list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
1402
1403 status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
1406 if (status) 1404 if (status)
1407 return status; 1405 goto out;
1408 } 1406 }
1409 1407
1410 status = 0; 1408 status = 0;
@@ -2661,8 +2659,8 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2661 __be32 *p; 2659 __be32 *p;
2662 2660
2663 if (!nfserr) { 2661 if (!nfserr) {
2664 RESERVE_SPACE(8); 2662 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
2665 WRITEMEM(commit->co_verf.data, 8); 2663 WRITEMEM(commit->co_verf.data, NFS4_VERIFIER_SIZE);
2666 ADJUST_ARGS(); 2664 ADJUST_ARGS();
2667 } 2665 }
2668 return nfserr; 2666 return nfserr;
@@ -2851,6 +2849,20 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
2851 WRITE32(0); /* XXX: is NULL principal ok? */ 2849 WRITE32(0); /* XXX: is NULL principal ok? */
2852 ADJUST_ARGS(); 2850 ADJUST_ARGS();
2853 break; 2851 break;
2852 case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
2853 switch (open->op_why_no_deleg) {
2854 case WND4_CONTENTION:
2855 case WND4_RESOURCE:
2856 RESERVE_SPACE(8);
2857 WRITE32(open->op_why_no_deleg);
2858 WRITE32(0); /* deleg signaling not supported yet */
2859 break;
2860 default:
2861 RESERVE_SPACE(4);
2862 WRITE32(open->op_why_no_deleg);
2863 }
2864 ADJUST_ARGS();
2865 break;
2854 default: 2866 default:
2855 BUG(); 2867 BUG();
2856 } 2868 }
@@ -3008,7 +3020,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3008 if (resp->xbuf->page_len) 3020 if (resp->xbuf->page_len)
3009 return nfserr_resource; 3021 return nfserr_resource;
3010 3022
3011 RESERVE_SPACE(8); /* verifier */ 3023 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
3012 savep = p; 3024 savep = p;
3013 3025
3014 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */ 3026 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
@@ -3209,9 +3221,9 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n
3209 __be32 *p; 3221 __be32 *p;
3210 3222
3211 if (!nfserr) { 3223 if (!nfserr) {
3212 RESERVE_SPACE(8 + sizeof(nfs4_verifier)); 3224 RESERVE_SPACE(8 + NFS4_VERIFIER_SIZE);
3213 WRITEMEM(&scd->se_clientid, 8); 3225 WRITEMEM(&scd->se_clientid, 8);
3214 WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier)); 3226 WRITEMEM(&scd->se_confirm, NFS4_VERIFIER_SIZE);
3215 ADJUST_ARGS(); 3227 ADJUST_ARGS();
3216 } 3228 }
3217 else if (nfserr == nfserr_clid_inuse) { 3229 else if (nfserr == nfserr_clid_inuse) {
@@ -3232,7 +3244,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
3232 RESERVE_SPACE(16); 3244 RESERVE_SPACE(16);
3233 WRITE32(write->wr_bytes_written); 3245 WRITE32(write->wr_bytes_written);
3234 WRITE32(write->wr_how_written); 3246 WRITE32(write->wr_how_written);
3235 WRITEMEM(write->wr_verifier.data, 8); 3247 WRITEMEM(write->wr_verifier.data, NFS4_VERIFIER_SIZE);
3236 ADJUST_ARGS(); 3248 ADJUST_ARGS();
3237 } 3249 }
3238 return nfserr; 3250 return nfserr;
@@ -3391,30 +3403,17 @@ __be32
3391nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, 3403nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
3392 struct nfsd4_test_stateid *test_stateid) 3404 struct nfsd4_test_stateid *test_stateid)
3393{ 3405{
3394 struct nfsd4_compoundargs *argp; 3406 struct nfsd4_test_stateid_id *stateid, *next;
3395 struct nfs4_client *cl = resp->cstate.session->se_client;
3396 stateid_t si;
3397 __be32 *p; 3407 __be32 *p;
3398 int i;
3399 int valid;
3400
3401 restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp);
3402 argp = test_stateid->ts_saved_args;
3403 3408
3404 RESERVE_SPACE(4); 3409 RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
3405 *p++ = htonl(test_stateid->ts_num_ids); 3410 *p++ = htonl(test_stateid->ts_num_ids);
3406 resp->p = p;
3407 3411
3408 nfs4_lock_state(); 3412 list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
3409 for (i = 0; i < test_stateid->ts_num_ids; i++) { 3413 *p++ = htonl(stateid->ts_id_status);
3410 nfsd4_decode_stateid(argp, &si);
3411 valid = nfs4_validate_stateid(cl, &si);
3412 RESERVE_SPACE(4);
3413 *p++ = htonl(valid);
3414 resp->p = p;
3415 } 3414 }
3416 nfs4_unlock_state();
3417 3415
3416 ADJUST_ARGS();
3418 return nfserr; 3417 return nfserr;
3419} 3418}
3420 3419
@@ -3532,7 +3531,7 @@ int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3532 if (length > session->se_fchannel.maxresp_sz) 3531 if (length > session->se_fchannel.maxresp_sz)
3533 return nfserr_rep_too_big; 3532 return nfserr_rep_too_big;
3534 3533
3535 if (slot->sl_cachethis == 1 && 3534 if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
3536 length > session->se_fchannel.maxresp_cached) 3535 length > session->se_fchannel.maxresp_cached)
3537 return nfserr_rep_too_big_to_cache; 3536 return nfserr_rep_too_big_to_cache;
3538 3537
@@ -3656,8 +3655,7 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
3656 if (nfsd4_has_session(cs)) { 3655 if (nfsd4_has_session(cs)) {
3657 if (cs->status != nfserr_replay_cache) { 3656 if (cs->status != nfserr_replay_cache) {
3658 nfsd4_store_cache_entry(resp); 3657 nfsd4_store_cache_entry(resp);
3659 dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__); 3658 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
3660 cs->slot->sl_inuse = false;
3661 } 3659 }
3662 /* Renew the clientid on success and on replay */ 3660 /* Renew the clientid on success and on replay */
3663 release_session_client(cs->session); 3661 release_session_client(cs->session);
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index fce472f5f39e..28dfad39f0c5 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -307,33 +307,37 @@ static void set_max_drc(void)
307 dprintk("%s nfsd_drc_max_mem %u \n", __func__, nfsd_drc_max_mem); 307 dprintk("%s nfsd_drc_max_mem %u \n", __func__, nfsd_drc_max_mem);
308} 308}
309 309
310int nfsd_create_serv(void) 310static int nfsd_get_default_max_blksize(void)
311{ 311{
312 int err = 0; 312 struct sysinfo i;
313 unsigned long long target;
314 unsigned long ret;
315
316 si_meminfo(&i);
317 target = (i.totalram - i.totalhigh) << PAGE_SHIFT;
318 /*
319 * Aim for 1/4096 of memory per thread This gives 1MB on 4Gig
320 * machines, but only uses 32K on 128M machines. Bottom out at
321 * 8K on 32M and smaller. Of course, this is only a default.
322 */
323 target >>= 12;
324
325 ret = NFSSVC_MAXBLKSIZE;
326 while (ret > target && ret >= 8*1024*2)
327 ret /= 2;
328 return ret;
329}
313 330
331int nfsd_create_serv(void)
332{
314 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 333 WARN_ON(!mutex_is_locked(&nfsd_mutex));
315 if (nfsd_serv) { 334 if (nfsd_serv) {
316 svc_get(nfsd_serv); 335 svc_get(nfsd_serv);
317 return 0; 336 return 0;
318 } 337 }
319 if (nfsd_max_blksize == 0) { 338 if (nfsd_max_blksize == 0)
320 /* choose a suitable default */ 339 nfsd_max_blksize = nfsd_get_default_max_blksize();
321 struct sysinfo i;
322 si_meminfo(&i);
323 /* Aim for 1/4096 of memory per thread
324 * This gives 1MB on 4Gig machines
325 * But only uses 32K on 128M machines.
326 * Bottom out at 8K on 32M and smaller.
327 * Of course, this is only a default.
328 */
329 nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
330 i.totalram <<= PAGE_SHIFT - 12;
331 while (nfsd_max_blksize > i.totalram &&
332 nfsd_max_blksize >= 8*1024*2)
333 nfsd_max_blksize /= 2;
334 }
335 nfsd_reset_versions(); 340 nfsd_reset_versions();
336
337 nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, 341 nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
338 nfsd_last_thread, nfsd, THIS_MODULE); 342 nfsd_last_thread, nfsd, THIS_MODULE);
339 if (nfsd_serv == NULL) 343 if (nfsd_serv == NULL)
@@ -341,7 +345,7 @@ int nfsd_create_serv(void)
341 345
342 set_max_drc(); 346 set_max_drc();
343 do_gettimeofday(&nfssvc_boot); /* record boot time */ 347 do_gettimeofday(&nfssvc_boot); /* record boot time */
344 return err; 348 return 0;
345} 349}
346 350
347int nfsd_nrpools(void) 351int nfsd_nrpools(void)
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index ffb5df1db94f..1e2b582bc9dc 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -128,12 +128,14 @@ static inline struct nfs4_delegation *delegstateid(struct nfs4_stid *s)
128 (NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE) 128 (NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE)
129 129
130struct nfsd4_slot { 130struct nfsd4_slot {
131 bool sl_inuse;
132 bool sl_cachethis;
133 u16 sl_opcnt;
134 u32 sl_seqid; 131 u32 sl_seqid;
135 __be32 sl_status; 132 __be32 sl_status;
136 u32 sl_datalen; 133 u32 sl_datalen;
134 u16 sl_opcnt;
135#define NFSD4_SLOT_INUSE (1 << 0)
136#define NFSD4_SLOT_CACHETHIS (1 << 1)
137#define NFSD4_SLOT_INITIALIZED (1 << 2)
138 u8 sl_flags;
137 char sl_data[]; 139 char sl_data[];
138}; 140};
139 141
@@ -196,18 +198,7 @@ struct nfsd4_session {
196 struct nfsd4_slot *se_slots[]; /* forward channel slots */ 198 struct nfsd4_slot *se_slots[]; /* forward channel slots */
197}; 199};
198 200
199static inline void 201extern void nfsd4_put_session(struct nfsd4_session *ses);
200nfsd4_put_session(struct nfsd4_session *ses)
201{
202 extern void free_session(struct kref *kref);
203 kref_put(&ses->se_ref, free_session);
204}
205
206static inline void
207nfsd4_get_session(struct nfsd4_session *ses)
208{
209 kref_get(&ses->se_ref);
210}
211 202
212/* formatted contents of nfs4_sessionid */ 203/* formatted contents of nfs4_sessionid */
213struct nfsd4_sessionid { 204struct nfsd4_sessionid {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index edf6d3ed8777..7423d712eb8c 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -737,12 +737,13 @@ static int nfsd_open_break_lease(struct inode *inode, int access)
737 737
738/* 738/*
739 * Open an existing file or directory. 739 * Open an existing file or directory.
740 * The access argument indicates the type of open (read/write/lock) 740 * The may_flags argument indicates the type of open (read/write/lock)
741 * and additional flags.
741 * N.B. After this call fhp needs an fh_put 742 * N.B. After this call fhp needs an fh_put
742 */ 743 */
743__be32 744__be32
744nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, 745nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
745 int access, struct file **filp) 746 int may_flags, struct file **filp)
746{ 747{
747 struct dentry *dentry; 748 struct dentry *dentry;
748 struct inode *inode; 749 struct inode *inode;
@@ -757,7 +758,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
757 * and (hopefully) checked permission - so allow OWNER_OVERRIDE 758 * and (hopefully) checked permission - so allow OWNER_OVERRIDE
758 * in case a chmod has now revoked permission. 759 * in case a chmod has now revoked permission.
759 */ 760 */
760 err = fh_verify(rqstp, fhp, type, access | NFSD_MAY_OWNER_OVERRIDE); 761 err = fh_verify(rqstp, fhp, type, may_flags | NFSD_MAY_OWNER_OVERRIDE);
761 if (err) 762 if (err)
762 goto out; 763 goto out;
763 764
@@ -768,7 +769,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
768 * or any access when mandatory locking enabled 769 * or any access when mandatory locking enabled
769 */ 770 */
770 err = nfserr_perm; 771 err = nfserr_perm;
771 if (IS_APPEND(inode) && (access & NFSD_MAY_WRITE)) 772 if (IS_APPEND(inode) && (may_flags & NFSD_MAY_WRITE))
772 goto out; 773 goto out;
773 /* 774 /*
774 * We must ignore files (but only files) which might have mandatory 775 * We must ignore files (but only files) which might have mandatory
@@ -781,12 +782,12 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
781 if (!inode->i_fop) 782 if (!inode->i_fop)
782 goto out; 783 goto out;
783 784
784 host_err = nfsd_open_break_lease(inode, access); 785 host_err = nfsd_open_break_lease(inode, may_flags);
785 if (host_err) /* NOMEM or WOULDBLOCK */ 786 if (host_err) /* NOMEM or WOULDBLOCK */
786 goto out_nfserr; 787 goto out_nfserr;
787 788
788 if (access & NFSD_MAY_WRITE) { 789 if (may_flags & NFSD_MAY_WRITE) {
789 if (access & NFSD_MAY_READ) 790 if (may_flags & NFSD_MAY_READ)
790 flags = O_RDWR|O_LARGEFILE; 791 flags = O_RDWR|O_LARGEFILE;
791 else 792 else
792 flags = O_WRONLY|O_LARGEFILE; 793 flags = O_WRONLY|O_LARGEFILE;
@@ -795,8 +796,15 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
795 flags, current_cred()); 796 flags, current_cred());
796 if (IS_ERR(*filp)) 797 if (IS_ERR(*filp))
797 host_err = PTR_ERR(*filp); 798 host_err = PTR_ERR(*filp);
798 else 799 else {
799 host_err = ima_file_check(*filp, access); 800 host_err = ima_file_check(*filp, may_flags);
801
802 if (may_flags & NFSD_MAY_64BIT_COOKIE)
803 (*filp)->f_mode |= FMODE_64BITHASH;
804 else
805 (*filp)->f_mode |= FMODE_32BITHASH;
806 }
807
800out_nfserr: 808out_nfserr:
801 err = nfserrno(host_err); 809 err = nfserrno(host_err);
802out: 810out:
@@ -2020,8 +2028,13 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
2020 __be32 err; 2028 __be32 err;
2021 struct file *file; 2029 struct file *file;
2022 loff_t offset = *offsetp; 2030 loff_t offset = *offsetp;
2031 int may_flags = NFSD_MAY_READ;
2032
2033 /* NFSv2 only supports 32 bit cookies */
2034 if (rqstp->rq_vers > 2)
2035 may_flags |= NFSD_MAY_64BIT_COOKIE;
2023 2036
2024 err = nfsd_open(rqstp, fhp, S_IFDIR, NFSD_MAY_READ, &file); 2037 err = nfsd_open(rqstp, fhp, S_IFDIR, may_flags, &file);
2025 if (err) 2038 if (err)
2026 goto out; 2039 goto out;
2027 2040
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 1dcd238e11a0..ec0611b2b738 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -27,6 +27,8 @@
27#define NFSD_MAY_BYPASS_GSS 0x400 27#define NFSD_MAY_BYPASS_GSS 0x400
28#define NFSD_MAY_READ_IF_EXEC 0x800 28#define NFSD_MAY_READ_IF_EXEC 0x800
29 29
30#define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */
31
30#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) 32#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
31#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) 33#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
32 34
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 2364747ee97d..1b3501598ab5 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -43,6 +43,13 @@
43#define NFSD4_MAX_TAGLEN 128 43#define NFSD4_MAX_TAGLEN 128
44#define XDR_LEN(n) (((n) + 3) & ~3) 44#define XDR_LEN(n) (((n) + 3) & ~3)
45 45
46#define CURRENT_STATE_ID_FLAG (1<<0)
47#define SAVED_STATE_ID_FLAG (1<<1)
48
49#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f))
50#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f))
51#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f))
52
46struct nfsd4_compound_state { 53struct nfsd4_compound_state {
47 struct svc_fh current_fh; 54 struct svc_fh current_fh;
48 struct svc_fh save_fh; 55 struct svc_fh save_fh;
@@ -54,6 +61,10 @@ struct nfsd4_compound_state {
54 size_t iovlen; 61 size_t iovlen;
55 u32 minorversion; 62 u32 minorversion;
56 u32 status; 63 u32 status;
64 stateid_t current_stateid;
65 stateid_t save_stateid;
66 /* to indicate current and saved state id presents */
67 u32 sid_flags;
57}; 68};
58 69
59static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs) 70static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
@@ -212,16 +223,19 @@ struct nfsd4_open {
212 struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */ 223 struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */
213 u32 op_delegate_type; /* request - CLAIM_PREV only */ 224 u32 op_delegate_type; /* request - CLAIM_PREV only */
214 stateid_t op_delegate_stateid; /* request - response */ 225 stateid_t op_delegate_stateid; /* request - response */
226 u32 op_why_no_deleg; /* response - DELEG_NONE_EXT only */
215 u32 op_create; /* request */ 227 u32 op_create; /* request */
216 u32 op_createmode; /* request */ 228 u32 op_createmode; /* request */
217 u32 op_bmval[3]; /* request */ 229 u32 op_bmval[3]; /* request */
218 struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ 230 struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
219 nfs4_verifier verf; /* EXCLUSIVE4 */ 231 nfs4_verifier op_verf __attribute__((aligned(32)));
232 /* EXCLUSIVE4 */
220 clientid_t op_clientid; /* request */ 233 clientid_t op_clientid; /* request */
221 struct xdr_netobj op_owner; /* request */ 234 struct xdr_netobj op_owner; /* request */
222 u32 op_seqid; /* request */ 235 u32 op_seqid; /* request */
223 u32 op_share_access; /* request */ 236 u32 op_share_access; /* request */
224 u32 op_share_deny; /* request */ 237 u32 op_share_deny; /* request */
238 u32 op_deleg_want; /* request */
225 stateid_t op_stateid; /* response */ 239 stateid_t op_stateid; /* response */
226 u32 op_recall; /* recall */ 240 u32 op_recall; /* recall */
227 struct nfsd4_change_info op_cinfo; /* response */ 241 struct nfsd4_change_info op_cinfo; /* response */
@@ -234,7 +248,6 @@ struct nfsd4_open {
234 struct nfs4_acl *op_acl; 248 struct nfs4_acl *op_acl;
235}; 249};
236#define op_iattr iattr 250#define op_iattr iattr
237#define op_verf verf
238 251
239struct nfsd4_open_confirm { 252struct nfsd4_open_confirm {
240 stateid_t oc_req_stateid /* request */; 253 stateid_t oc_req_stateid /* request */;
@@ -245,8 +258,9 @@ struct nfsd4_open_confirm {
245struct nfsd4_open_downgrade { 258struct nfsd4_open_downgrade {
246 stateid_t od_stateid; 259 stateid_t od_stateid;
247 u32 od_seqid; 260 u32 od_seqid;
248 u32 od_share_access; 261 u32 od_share_access; /* request */
249 u32 od_share_deny; 262 u32 od_deleg_want; /* request */
263 u32 od_share_deny; /* request */
250}; 264};
251 265
252 266
@@ -343,10 +357,15 @@ struct nfsd4_saved_compoundargs {
343 struct page **pagelist; 357 struct page **pagelist;
344}; 358};
345 359
360struct nfsd4_test_stateid_id {
361 __be32 ts_id_status;
362 stateid_t ts_id_stateid;
363 struct list_head ts_id_list;
364};
365
346struct nfsd4_test_stateid { 366struct nfsd4_test_stateid {
347 __be32 ts_num_ids; 367 __be32 ts_num_ids;
348 struct nfsd4_compoundargs *ts_saved_args; 368 struct list_head ts_stateid_list;
349 struct nfsd4_saved_compoundargs ts_savedp;
350}; 369};
351 370
352struct nfsd4_free_stateid { 371struct nfsd4_free_stateid {
@@ -503,7 +522,8 @@ static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
503 522
504static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) 523static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
505{ 524{
506 return !resp->cstate.slot->sl_cachethis || nfsd4_is_solo_sequence(resp); 525 return !(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
526 || nfsd4_is_solo_sequence(resp);
507} 527}
508 528
509#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) 529#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)