aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-29 17:53:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-29 17:53:25 -0400
commit71db34fc4330f7c784397acb9f1e6ee7f7b32eb2 (patch)
tree77dd08f6f778a799dcd0c48eb72d0742349df235 /fs/nfsd/nfs4proc.c
parent50483c3268918ee51a56d1baa39b9149d2d0d521 (diff)
parent797a9d797f8483bb67f265c761b76dcd5a077a23 (diff)
Merge branch 'for-3.4' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from Bruce Fields: Highlights: - Benny Halevy and Tigran Mkrtchyan implemented some more 4.1 features, moving us closer to a complete 4.1 implementation. - Bernd Schubert fixed a long-standing problem with readdir cookies on ext2/3/4. - Jeff Layton performed a long-overdue overhaul of the server reboot recovery code which will allow us to deprecate the current code (a rather unusual user of the vfs), and give us some needed flexibility for further improvements. - Like the client, we now support numeric uid's and gid's in the auth_sys case, allowing easier upgrades from NFSv2/v3 to v4.x. Plus miscellaneous bugfixes and cleanup. Thanks to everyone! There are also some delegation fixes waiting on vfs review that I suppose will have to wait for 3.5. With that done I think we'll finally turn off the "EXPERIMENTAL" dependency for v4 (though that's mostly symbolic as it's been on by default in distro's for a while). And the list of 4.1 todo's should be achievable for 3.5 as well: http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues though we may still want a bit more experience with it before turning it on by default. * 'for-3.4' of git://linux-nfs.org/~bfields/linux: (55 commits) nfsd: only register cld pipe notifier when CONFIG_NFSD_V4 is enabled nfsd4: use auth_unix unconditionally on backchannel nfsd: fix NULL pointer dereference in cld_pipe_downcall nfsd4: memory corruption in numeric_name_to_id() sunrpc: skip portmap calls on sessions backchannel nfsd4: allow numeric idmapping nfsd: don't allow legacy client tracker init for anything but init_net nfsd: add notifier to handle mount/unmount of rpc_pipefs sb nfsd: add the infrastructure to handle the cld upcall nfsd: add a header describing upcall to nfsdcld nfsd: add a per-net-namespace struct for nfsd sunrpc: create nfsd dir in rpc_pipefs nfsd: add nfsd4_client_tracking_ops struct and a way to set it nfsd: convert nfs4_client->cl_cb_flags to a generic flags field NFSD: Fix nfs4_verifier memory alignment NFSD: Fix warnings when NFSD_DEBUG is not defined nfsd: vfs_llseek() with 32 or 64 bit offsets (hashes) nfsd: rename 'int access' to 'int may_flags' in nfsd_open() ext4: return 32/64-bit dir name hash according to usage type fs: add new FMODE flags: FMODE_32bithash and FMODE_64bithash ...
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r--fs/nfsd/nfs4proc.c118
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)
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,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
493static 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
484static __be32 502static __be32
485nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 503nfsd4_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)
1000typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1012typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
1001 void *); 1013 void *);
1002typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); 1014typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
1015typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *);
1016typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *);
1003 1017
1004enum nfsd4_op_flags { 1018enum 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
1030struct nfsd4_operation { 1048struct 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
1038static struct nfsd4_operation nfsd4_ops[]; 1058static struct nfsd4_operation nfsd4_ops[];
1039 1059
1060#ifdef NFSD_DEBUG
1040static const char *nfsd4_op_name(unsigned opnum); 1061static 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
1226encode_op: 1258encode_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
1677static const char *nfsd4_op_name(unsigned opnum) 1724static 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
1685struct nfsd4_voidargs { int dummy; }; 1733struct nfsd4_voidargs { int dummy; };