diff options
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 118 |
1 files changed, 83 insertions, 35 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 896da74ec563..2ed14dfd00a2 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) | |||
192 | static __be32 | 193 | static __be32 |
193 | do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) | 194 | do_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); | ||
259 | out: | 261 | out: |
260 | fh_put(&resfh); | 262 | fh_put(resfh); |
263 | kfree(resfh); | ||
261 | return status; | 264 | return status; |
262 | } | 265 | } |
263 | 266 | ||
@@ -310,16 +313,14 @@ 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 |
319 | * Before RECLAIM_COMPLETE done, server should deny new lock | 319 | * Before RECLAIM_COMPLETE done, server should deny new lock |
320 | */ | 320 | */ |
321 | if (nfsd4_has_session(cstate) && | 321 | if (nfsd4_has_session(cstate) && |
322 | !cstate->session->se_client->cl_firststate && | 322 | !test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE, |
323 | &cstate->session->se_client->cl_flags) && | ||
323 | open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) | 324 | open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) |
324 | return nfserr_grace; | 325 | return nfserr_grace; |
325 | 326 | ||
@@ -452,6 +453,10 @@ nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
452 | return nfserr_restorefh; | 453 | return nfserr_restorefh; |
453 | 454 | ||
454 | fh_dup2(&cstate->current_fh, &cstate->save_fh); | 455 | fh_dup2(&cstate->current_fh, &cstate->save_fh); |
456 | if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) { | ||
457 | memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t)); | ||
458 | SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); | ||
459 | } | ||
455 | return nfs_ok; | 460 | return nfs_ok; |
456 | } | 461 | } |
457 | 462 | ||
@@ -463,6 +468,10 @@ nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
463 | return nfserr_nofilehandle; | 468 | return nfserr_nofilehandle; |
464 | 469 | ||
465 | fh_dup2(&cstate->save_fh, &cstate->current_fh); | 470 | fh_dup2(&cstate->save_fh, &cstate->current_fh); |
471 | if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) { | ||
472 | memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t)); | ||
473 | SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG); | ||
474 | } | ||
466 | return nfs_ok; | 475 | return nfs_ok; |
467 | } | 476 | } |
468 | 477 | ||
@@ -481,14 +490,20 @@ nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
481 | &access->ac_supported); | 490 | &access->ac_supported); |
482 | } | 491 | } |
483 | 492 | ||
493 | static void gen_boot_verifier(nfs4_verifier *verifier) | ||
494 | { | ||
495 | __be32 verf[2]; | ||
496 | |||
497 | verf[0] = (__be32)nfssvc_boot.tv_sec; | ||
498 | verf[1] = (__be32)nfssvc_boot.tv_usec; | ||
499 | memcpy(verifier->data, verf, sizeof(verifier->data)); | ||
500 | } | ||
501 | |||
484 | static __be32 | 502 | static __be32 |
485 | nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 503 | nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
486 | struct nfsd4_commit *commit) | 504 | struct nfsd4_commit *commit) |
487 | { | 505 | { |
488 | u32 *p = (u32 *)commit->co_verf.data; | 506 | 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, | 507 | return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, |
493 | commit->co_count); | 508 | commit->co_count); |
494 | } | 509 | } |
@@ -865,7 +880,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
865 | { | 880 | { |
866 | stateid_t *stateid = &write->wr_stateid; | 881 | stateid_t *stateid = &write->wr_stateid; |
867 | struct file *filp = NULL; | 882 | struct file *filp = NULL; |
868 | u32 *p; | ||
869 | __be32 status = nfs_ok; | 883 | __be32 status = nfs_ok; |
870 | unsigned long cnt; | 884 | unsigned long cnt; |
871 | 885 | ||
@@ -887,9 +901,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
887 | 901 | ||
888 | cnt = write->wr_buflen; | 902 | cnt = write->wr_buflen; |
889 | write->wr_how_written = write->wr_stable_how; | 903 | write->wr_how_written = write->wr_stable_how; |
890 | p = (u32 *)write->wr_verifier.data; | 904 | gen_boot_verifier(&write->wr_verifier); |
891 | *p++ = nfssvc_boot.tv_sec; | ||
892 | *p++ = nfssvc_boot.tv_usec; | ||
893 | 905 | ||
894 | status = nfsd_write(rqstp, &cstate->current_fh, filp, | 906 | status = nfsd_write(rqstp, &cstate->current_fh, filp, |
895 | write->wr_offset, rqstp->rq_vec, write->wr_vlen, | 907 | write->wr_offset, rqstp->rq_vec, write->wr_vlen, |
@@ -1000,6 +1012,8 @@ static inline void nfsd4_increment_op_stats(u32 opnum) | |||
1000 | typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, | 1012 | typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, |
1001 | void *); | 1013 | void *); |
1002 | typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); | 1014 | typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); |
1015 | typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *); | ||
1016 | typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *); | ||
1003 | 1017 | ||
1004 | enum nfsd4_op_flags { | 1018 | enum nfsd4_op_flags { |
1005 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ | 1019 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ |
@@ -1025,6 +1039,10 @@ enum nfsd4_op_flags { | |||
1025 | * the v4.0 case). | 1039 | * the v4.0 case). |
1026 | */ | 1040 | */ |
1027 | OP_CACHEME = 1 << 6, | 1041 | OP_CACHEME = 1 << 6, |
1042 | /* | ||
1043 | * These are ops which clear current state id. | ||
1044 | */ | ||
1045 | OP_CLEAR_STATEID = 1 << 7, | ||
1028 | }; | 1046 | }; |
1029 | 1047 | ||
1030 | struct nfsd4_operation { | 1048 | struct nfsd4_operation { |
@@ -1033,11 +1051,15 @@ struct nfsd4_operation { | |||
1033 | char *op_name; | 1051 | char *op_name; |
1034 | /* Try to get response size before operation */ | 1052 | /* Try to get response size before operation */ |
1035 | nfsd4op_rsize op_rsize_bop; | 1053 | nfsd4op_rsize op_rsize_bop; |
1054 | stateid_setter op_get_currentstateid; | ||
1055 | stateid_getter op_set_currentstateid; | ||
1036 | }; | 1056 | }; |
1037 | 1057 | ||
1038 | static struct nfsd4_operation nfsd4_ops[]; | 1058 | static struct nfsd4_operation nfsd4_ops[]; |
1039 | 1059 | ||
1060 | #ifdef NFSD_DEBUG | ||
1040 | static const char *nfsd4_op_name(unsigned opnum); | 1061 | static const char *nfsd4_op_name(unsigned opnum); |
1062 | #endif | ||
1041 | 1063 | ||
1042 | /* | 1064 | /* |
1043 | * Enforce NFSv4.1 COMPOUND ordering rules: | 1065 | * Enforce NFSv4.1 COMPOUND ordering rules: |
@@ -1215,13 +1237,23 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1215 | if (op->status) | 1237 | if (op->status) |
1216 | goto encode_op; | 1238 | goto encode_op; |
1217 | 1239 | ||
1218 | if (opdesc->op_func) | 1240 | if (opdesc->op_func) { |
1241 | if (opdesc->op_get_currentstateid) | ||
1242 | opdesc->op_get_currentstateid(cstate, &op->u); | ||
1219 | op->status = opdesc->op_func(rqstp, cstate, &op->u); | 1243 | op->status = opdesc->op_func(rqstp, cstate, &op->u); |
1220 | else | 1244 | } else |
1221 | BUG_ON(op->status == nfs_ok); | 1245 | BUG_ON(op->status == nfs_ok); |
1222 | 1246 | ||
1223 | if (!op->status && need_wrongsec_check(rqstp)) | 1247 | if (!op->status) { |
1224 | op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); | 1248 | if (opdesc->op_set_currentstateid) |
1249 | opdesc->op_set_currentstateid(cstate, &op->u); | ||
1250 | |||
1251 | if (opdesc->op_flags & OP_CLEAR_STATEID) | ||
1252 | clear_current_stateid(cstate); | ||
1253 | |||
1254 | if (need_wrongsec_check(rqstp)) | ||
1255 | op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); | ||
1256 | } | ||
1225 | 1257 | ||
1226 | encode_op: | 1258 | encode_op: |
1227 | /* Only from SEQUENCE */ | 1259 | /* Only from SEQUENCE */ |
@@ -1413,6 +1445,8 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1413 | .op_flags = OP_MODIFIES_SOMETHING, | 1445 | .op_flags = OP_MODIFIES_SOMETHING, |
1414 | .op_name = "OP_CLOSE", | 1446 | .op_name = "OP_CLOSE", |
1415 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, | 1447 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, |
1448 | .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid, | ||
1449 | .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid, | ||
1416 | }, | 1450 | }, |
1417 | [OP_COMMIT] = { | 1451 | [OP_COMMIT] = { |
1418 | .op_func = (nfsd4op_func)nfsd4_commit, | 1452 | .op_func = (nfsd4op_func)nfsd4_commit, |
@@ -1422,7 +1456,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1422 | }, | 1456 | }, |
1423 | [OP_CREATE] = { | 1457 | [OP_CREATE] = { |
1424 | .op_func = (nfsd4op_func)nfsd4_create, | 1458 | .op_func = (nfsd4op_func)nfsd4_create, |
1425 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, | 1459 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID, |
1426 | .op_name = "OP_CREATE", | 1460 | .op_name = "OP_CREATE", |
1427 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize, | 1461 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize, |
1428 | }, | 1462 | }, |
@@ -1431,6 +1465,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1431 | .op_flags = OP_MODIFIES_SOMETHING, | 1465 | .op_flags = OP_MODIFIES_SOMETHING, |
1432 | .op_name = "OP_DELEGRETURN", | 1466 | .op_name = "OP_DELEGRETURN", |
1433 | .op_rsize_bop = nfsd4_only_status_rsize, | 1467 | .op_rsize_bop = nfsd4_only_status_rsize, |
1468 | .op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid, | ||
1434 | }, | 1469 | }, |
1435 | [OP_GETATTR] = { | 1470 | [OP_GETATTR] = { |
1436 | .op_func = (nfsd4op_func)nfsd4_getattr, | 1471 | .op_func = (nfsd4op_func)nfsd4_getattr, |
@@ -1453,6 +1488,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1453 | .op_flags = OP_MODIFIES_SOMETHING, | 1488 | .op_flags = OP_MODIFIES_SOMETHING, |
1454 | .op_name = "OP_LOCK", | 1489 | .op_name = "OP_LOCK", |
1455 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, | 1490 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, |
1491 | .op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid, | ||
1456 | }, | 1492 | }, |
1457 | [OP_LOCKT] = { | 1493 | [OP_LOCKT] = { |
1458 | .op_func = (nfsd4op_func)nfsd4_lockt, | 1494 | .op_func = (nfsd4op_func)nfsd4_lockt, |
@@ -1463,15 +1499,16 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1463 | .op_flags = OP_MODIFIES_SOMETHING, | 1499 | .op_flags = OP_MODIFIES_SOMETHING, |
1464 | .op_name = "OP_LOCKU", | 1500 | .op_name = "OP_LOCKU", |
1465 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, | 1501 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, |
1502 | .op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid, | ||
1466 | }, | 1503 | }, |
1467 | [OP_LOOKUP] = { | 1504 | [OP_LOOKUP] = { |
1468 | .op_func = (nfsd4op_func)nfsd4_lookup, | 1505 | .op_func = (nfsd4op_func)nfsd4_lookup, |
1469 | .op_flags = OP_HANDLES_WRONGSEC, | 1506 | .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, |
1470 | .op_name = "OP_LOOKUP", | 1507 | .op_name = "OP_LOOKUP", |
1471 | }, | 1508 | }, |
1472 | [OP_LOOKUPP] = { | 1509 | [OP_LOOKUPP] = { |
1473 | .op_func = (nfsd4op_func)nfsd4_lookupp, | 1510 | .op_func = (nfsd4op_func)nfsd4_lookupp, |
1474 | .op_flags = OP_HANDLES_WRONGSEC, | 1511 | .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, |
1475 | .op_name = "OP_LOOKUPP", | 1512 | .op_name = "OP_LOOKUPP", |
1476 | }, | 1513 | }, |
1477 | [OP_NVERIFY] = { | 1514 | [OP_NVERIFY] = { |
@@ -1483,6 +1520,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1483 | .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, | 1520 | .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, |
1484 | .op_name = "OP_OPEN", | 1521 | .op_name = "OP_OPEN", |
1485 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, | 1522 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, |
1523 | .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid, | ||
1486 | }, | 1524 | }, |
1487 | [OP_OPEN_CONFIRM] = { | 1525 | [OP_OPEN_CONFIRM] = { |
1488 | .op_func = (nfsd4op_func)nfsd4_open_confirm, | 1526 | .op_func = (nfsd4op_func)nfsd4_open_confirm, |
@@ -1495,25 +1533,30 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1495 | .op_flags = OP_MODIFIES_SOMETHING, | 1533 | .op_flags = OP_MODIFIES_SOMETHING, |
1496 | .op_name = "OP_OPEN_DOWNGRADE", | 1534 | .op_name = "OP_OPEN_DOWNGRADE", |
1497 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, | 1535 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, |
1536 | .op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid, | ||
1537 | .op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid, | ||
1498 | }, | 1538 | }, |
1499 | [OP_PUTFH] = { | 1539 | [OP_PUTFH] = { |
1500 | .op_func = (nfsd4op_func)nfsd4_putfh, | 1540 | .op_func = (nfsd4op_func)nfsd4_putfh, |
1501 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | 1541 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1502 | | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, | 1542 | | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING |
1543 | | OP_CLEAR_STATEID, | ||
1503 | .op_name = "OP_PUTFH", | 1544 | .op_name = "OP_PUTFH", |
1504 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, | 1545 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, |
1505 | }, | 1546 | }, |
1506 | [OP_PUTPUBFH] = { | 1547 | [OP_PUTPUBFH] = { |
1507 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1548 | .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1508 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | 1549 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1509 | | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, | 1550 | | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING |
1551 | | OP_CLEAR_STATEID, | ||
1510 | .op_name = "OP_PUTPUBFH", | 1552 | .op_name = "OP_PUTPUBFH", |
1511 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, | 1553 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, |
1512 | }, | 1554 | }, |
1513 | [OP_PUTROOTFH] = { | 1555 | [OP_PUTROOTFH] = { |
1514 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1556 | .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1515 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | 1557 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1516 | | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, | 1558 | | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING |
1559 | | OP_CLEAR_STATEID, | ||
1517 | .op_name = "OP_PUTROOTFH", | 1560 | .op_name = "OP_PUTROOTFH", |
1518 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, | 1561 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, |
1519 | }, | 1562 | }, |
@@ -1522,6 +1565,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1522 | .op_flags = OP_MODIFIES_SOMETHING, | 1565 | .op_flags = OP_MODIFIES_SOMETHING, |
1523 | .op_name = "OP_READ", | 1566 | .op_name = "OP_READ", |
1524 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, | 1567 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, |
1568 | .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid, | ||
1525 | }, | 1569 | }, |
1526 | [OP_READDIR] = { | 1570 | [OP_READDIR] = { |
1527 | .op_func = (nfsd4op_func)nfsd4_readdir, | 1571 | .op_func = (nfsd4op_func)nfsd4_readdir, |
@@ -1576,6 +1620,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1576 | .op_name = "OP_SETATTR", | 1620 | .op_name = "OP_SETATTR", |
1577 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, | 1621 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, |
1578 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize, | 1622 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize, |
1623 | .op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid, | ||
1579 | }, | 1624 | }, |
1580 | [OP_SETCLIENTID] = { | 1625 | [OP_SETCLIENTID] = { |
1581 | .op_func = (nfsd4op_func)nfsd4_setclientid, | 1626 | .op_func = (nfsd4op_func)nfsd4_setclientid, |
@@ -1600,6 +1645,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1600 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, | 1645 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, |
1601 | .op_name = "OP_WRITE", | 1646 | .op_name = "OP_WRITE", |
1602 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, | 1647 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, |
1648 | .op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid, | ||
1603 | }, | 1649 | }, |
1604 | [OP_RELEASE_LOCKOWNER] = { | 1650 | [OP_RELEASE_LOCKOWNER] = { |
1605 | .op_func = (nfsd4op_func)nfsd4_release_lockowner, | 1651 | .op_func = (nfsd4op_func)nfsd4_release_lockowner, |
@@ -1674,12 +1720,14 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1674 | }, | 1720 | }, |
1675 | }; | 1721 | }; |
1676 | 1722 | ||
1723 | #ifdef NFSD_DEBUG | ||
1677 | static const char *nfsd4_op_name(unsigned opnum) | 1724 | static const char *nfsd4_op_name(unsigned opnum) |
1678 | { | 1725 | { |
1679 | if (opnum < ARRAY_SIZE(nfsd4_ops)) | 1726 | if (opnum < ARRAY_SIZE(nfsd4_ops)) |
1680 | return nfsd4_ops[opnum].op_name; | 1727 | return nfsd4_ops[opnum].op_name; |
1681 | return "unknown_operation"; | 1728 | return "unknown_operation"; |
1682 | } | 1729 | } |
1730 | #endif | ||
1683 | 1731 | ||
1684 | #define nfsd4_voidres nfsd4_voidargs | 1732 | #define nfsd4_voidres nfsd4_voidargs |
1685 | struct nfsd4_voidargs { int dummy; }; | 1733 | struct nfsd4_voidargs { int dummy; }; |