Commit 4dc6ec00f6347b72312fa41dfc587d5302b05544
1 parent
ab707e1565
Exists in
master
and in
39 other branches
nfsd4: implement reclaim_complete
This is a mandatory operation. Also, here (not in open) is where we should be committing the reboot recovery information. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Showing 5 changed files with 53 additions and 5 deletions Side-by-side Diff
Documentation/filesystems/nfs/nfs41-server.txt
... | ... | @@ -137,7 +137,7 @@ |
137 | 137 | | READ | REQ | | Section 18.22 | |
138 | 138 | | READDIR | REQ | | Section 18.23 | |
139 | 139 | | READLINK | OPT | | Section 18.24 | |
140 | -NS | RECLAIM_COMPLETE | REQ | | Section 18.51 | | |
140 | + | RECLAIM_COMPLETE | REQ | | Section 18.51 | | |
141 | 141 | | RELEASE_LOCKOWNER | MNI | | N/A | |
142 | 142 | | REMOVE | REQ | | Section 18.25 | |
143 | 143 | | RENAME | REQ | | Section 18.26 | |
fs/nfsd/nfs4proc.c
... | ... | @@ -1312,6 +1312,11 @@ |
1312 | 1312 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, |
1313 | 1313 | .op_name = "OP_SEQUENCE", |
1314 | 1314 | }, |
1315 | + [OP_RECLAIM_COMPLETE] = { | |
1316 | + .op_func = (nfsd4op_func)nfsd4_reclaim_complete, | |
1317 | + .op_flags = ALLOWED_WITHOUT_FH, | |
1318 | + .op_name = "OP_RECLAIM_COMPLETE", | |
1319 | + }, | |
1315 | 1320 | }; |
1316 | 1321 | |
1317 | 1322 | static const char *nfsd4_op_name(unsigned opnum) |
fs/nfsd/nfs4state.c
... | ... | @@ -1502,6 +1502,35 @@ |
1502 | 1502 | } |
1503 | 1503 | |
1504 | 1504 | __be32 |
1505 | +nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) | |
1506 | +{ | |
1507 | + if (rc->rca_one_fs) { | |
1508 | + if (!cstate->current_fh.fh_dentry) | |
1509 | + return nfserr_nofilehandle; | |
1510 | + /* | |
1511 | + * We don't take advantage of the rca_one_fs case. | |
1512 | + * That's OK, it's optional, we can safely ignore it. | |
1513 | + */ | |
1514 | + return nfs_ok; | |
1515 | + } | |
1516 | + nfs4_lock_state(); | |
1517 | + if (is_client_expired(cstate->session->se_client)) { | |
1518 | + nfs4_unlock_state(); | |
1519 | + /* | |
1520 | + * The following error isn't really legal. | |
1521 | + * But we only get here if the client just explicitly | |
1522 | + * destroyed the client. Surely it no longer cares what | |
1523 | + * error it gets back on an operation for the dead | |
1524 | + * client. | |
1525 | + */ | |
1526 | + return nfserr_stale_clientid; | |
1527 | + } | |
1528 | + nfsd4_create_clid_dir(cstate->session->se_client); | |
1529 | + nfs4_unlock_state(); | |
1530 | + return nfs_ok; | |
1531 | +} | |
1532 | + | |
1533 | +__be32 | |
1505 | 1534 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
1506 | 1535 | struct nfsd4_setclientid *setclid) |
1507 | 1536 | { |
1508 | 1537 | |
... | ... | @@ -2510,10 +2539,8 @@ |
2510 | 2539 | } |
2511 | 2540 | memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); |
2512 | 2541 | |
2513 | - if (nfsd4_has_session(&resp->cstate)) { | |
2542 | + if (nfsd4_has_session(&resp->cstate)) | |
2514 | 2543 | open->op_stateowner->so_confirmed = 1; |
2515 | - nfsd4_create_clid_dir(open->op_stateowner->so_client); | |
2516 | - } | |
2517 | 2544 | |
2518 | 2545 | /* |
2519 | 2546 | * Attempt to hand out a delegation. No error return, because the |
fs/nfsd/nfs4xdr.c
... | ... | @@ -1234,6 +1234,16 @@ |
1234 | 1234 | DECODE_TAIL; |
1235 | 1235 | } |
1236 | 1236 | |
1237 | +static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) | |
1238 | +{ | |
1239 | + DECODE_HEAD; | |
1240 | + | |
1241 | + READ_BUF(4); | |
1242 | + READ32(rc->rca_one_fs); | |
1243 | + | |
1244 | + DECODE_TAIL; | |
1245 | +} | |
1246 | + | |
1237 | 1247 | static __be32 |
1238 | 1248 | nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) |
1239 | 1249 | { |
... | ... | @@ -1346,7 +1356,7 @@ |
1346 | 1356 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, |
1347 | 1357 | [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, |
1348 | 1358 | [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, |
1349 | - [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_notsupp, | |
1359 | + [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, | |
1350 | 1360 | }; |
1351 | 1361 | |
1352 | 1362 | struct nfsd4_minorversion_ops { |
fs/nfsd/xdr4.h
... | ... | @@ -381,6 +381,10 @@ |
381 | 381 | struct nfs4_sessionid sessionid; |
382 | 382 | }; |
383 | 383 | |
384 | +struct nfsd4_reclaim_complete { | |
385 | + u32 rca_one_fs; | |
386 | +}; | |
387 | + | |
384 | 388 | struct nfsd4_op { |
385 | 389 | int opnum; |
386 | 390 | __be32 status; |
... | ... | @@ -421,6 +425,7 @@ |
421 | 425 | struct nfsd4_create_session create_session; |
422 | 426 | struct nfsd4_destroy_session destroy_session; |
423 | 427 | struct nfsd4_sequence sequence; |
428 | + struct nfsd4_reclaim_complete reclaim_complete; | |
424 | 429 | } u; |
425 | 430 | struct nfs4_replay * replay; |
426 | 431 | }; |
... | ... | @@ -523,6 +528,7 @@ |
523 | 528 | extern __be32 nfsd4_destroy_session(struct svc_rqst *, |
524 | 529 | struct nfsd4_compound_state *, |
525 | 530 | struct nfsd4_destroy_session *); |
531 | +__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); | |
526 | 532 | extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, |
527 | 533 | struct nfsd4_open *open); |
528 | 534 | extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, |