diff options
| -rw-r--r-- | Documentation/filesystems/nfs/nfs41-server.txt | 2 | ||||
| -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 |
5 files changed, 53 insertions, 5 deletions
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt index 6a53a84afc72..04884914a1c8 100644 --- a/Documentation/filesystems/nfs/nfs41-server.txt +++ b/Documentation/filesystems/nfs/nfs41-server.txt | |||
| @@ -137,7 +137,7 @@ NS*| OPENATTR | OPT | | Section 18.17 | | |||
| 137 | | READ | REQ | | Section 18.22 | | 137 | | READ | REQ | | Section 18.22 | |
| 138 | | READDIR | REQ | | Section 18.23 | | 138 | | READDIR | REQ | | Section 18.23 | |
| 139 | | READLINK | OPT | | Section 18.24 | | 139 | | READLINK | OPT | | Section 18.24 | |
| 140 | NS | RECLAIM_COMPLETE | REQ | | Section 18.51 | | 140 | | RECLAIM_COMPLETE | REQ | | Section 18.51 | |
| 141 | | RELEASE_LOCKOWNER | MNI | | N/A | | 141 | | RELEASE_LOCKOWNER | MNI | | N/A | |
| 142 | | REMOVE | REQ | | Section 18.25 | | 142 | | REMOVE | REQ | | Section 18.25 | |
| 143 | | RENAME | REQ | | Section 18.26 | | 143 | | RENAME | REQ | | Section 18.26 | |
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, |
