diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2010-04-19 15:11:28 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2010-05-13 12:03:11 -0400 |
commit | 4dc6ec00f6347b72312fa41dfc587d5302b05544 (patch) | |
tree | fbb00e0c8341561f155a6dcd6fc5f83282c638b0 /fs/nfsd | |
parent | ab707e156593ff7fffd615757332dbff6616836a (diff) |
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>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 5 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 33 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 12 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 6 |
4 files changed, 52 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index e2dc9608281b..59ec449b0c7f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -1312,6 +1312,11 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1312 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, | 1312 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, |
1313 | .op_name = "OP_SEQUENCE", | 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 | static const char *nfsd4_op_name(unsigned opnum) | 1322 | static const char *nfsd4_op_name(unsigned opnum) |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ede9dde52fe8..84b0fe9a262a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1502,6 +1502,35 @@ out: | |||
1502 | } | 1502 | } |
1503 | 1503 | ||
1504 | __be32 | 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 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 1534 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
1506 | struct nfsd4_setclientid *setclid) | 1535 | struct nfsd4_setclientid *setclid) |
1507 | { | 1536 | { |
@@ -2510,10 +2539,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
2510 | } | 2539 | } |
2511 | memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); | 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 | open->op_stateowner->so_confirmed = 1; | 2543 | open->op_stateowner->so_confirmed = 1; |
2515 | nfsd4_create_clid_dir(open->op_stateowner->so_client); | ||
2516 | } | ||
2517 | 2544 | ||
2518 | /* | 2545 | /* |
2519 | * Attempt to hand out a delegation. No error return, because the | 2546 | * Attempt to hand out a delegation. No error return, because the |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 126d0caabb3c..ac17a7080239 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1234,6 +1234,16 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, | |||
1234 | DECODE_TAIL; | 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 | static __be32 | 1247 | static __be32 |
1238 | nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) | 1248 | nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) |
1239 | { | 1249 | { |
@@ -1346,7 +1356,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { | |||
1346 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, | 1356 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, |
1347 | [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, | 1357 | [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, |
1348 | [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, | 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 | struct nfsd4_minorversion_ops { | 1362 | struct nfsd4_minorversion_ops { |
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index c28958ec216c..4d476ff08ae6 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -381,6 +381,10 @@ struct nfsd4_destroy_session { | |||
381 | struct nfs4_sessionid sessionid; | 381 | struct nfs4_sessionid sessionid; |
382 | }; | 382 | }; |
383 | 383 | ||
384 | struct nfsd4_reclaim_complete { | ||
385 | u32 rca_one_fs; | ||
386 | }; | ||
387 | |||
384 | struct nfsd4_op { | 388 | struct nfsd4_op { |
385 | int opnum; | 389 | int opnum; |
386 | __be32 status; | 390 | __be32 status; |
@@ -421,6 +425,7 @@ struct nfsd4_op { | |||
421 | struct nfsd4_create_session create_session; | 425 | struct nfsd4_create_session create_session; |
422 | struct nfsd4_destroy_session destroy_session; | 426 | struct nfsd4_destroy_session destroy_session; |
423 | struct nfsd4_sequence sequence; | 427 | struct nfsd4_sequence sequence; |
428 | struct nfsd4_reclaim_complete reclaim_complete; | ||
424 | } u; | 429 | } u; |
425 | struct nfs4_replay * replay; | 430 | struct nfs4_replay * replay; |
426 | }; | 431 | }; |
@@ -523,6 +528,7 @@ extern __be32 nfsd4_sequence(struct svc_rqst *, | |||
523 | extern __be32 nfsd4_destroy_session(struct svc_rqst *, | 528 | extern __be32 nfsd4_destroy_session(struct svc_rqst *, |
524 | struct nfsd4_compound_state *, | 529 | struct nfsd4_compound_state *, |
525 | struct nfsd4_destroy_session *); | 530 | struct nfsd4_destroy_session *); |
531 | __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); | ||
526 | extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, | 532 | extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, |
527 | struct nfsd4_open *open); | 533 | struct nfsd4_open *open); |
528 | extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, | 534 | extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, |