diff options
author | Mi Jinlong <mijinlong@cn.fujitsu.com> | 2011-10-20 05:51:39 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-10-24 04:24:30 -0400 |
commit | 345c284290cabb5484df909303e73d6def8ec8ec (patch) | |
tree | 1a853fe648230fefee758e36bd1ab141639c0b83 /fs/nfsd | |
parent | 92bac8c5d60623167c6802b1f125e6d623708185 (diff) |
nfs41: implement DESTROY_CLIENTID operation
According to rfc5661 18.50, implement DESTROY_CLIENTID operation.
Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 44 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 12 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 5 |
4 files changed, 61 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 458ebb6b59c..fa383361bc6 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -1645,7 +1645,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1645 | .op_name = "OP_SEQUENCE", | 1645 | .op_name = "OP_SEQUENCE", |
1646 | }, | 1646 | }, |
1647 | [OP_DESTROY_CLIENTID] = { | 1647 | [OP_DESTROY_CLIENTID] = { |
1648 | .op_func = NULL, | 1648 | .op_func = (nfsd4op_func)nfsd4_destroy_clientid, |
1649 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP | 1649 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP |
1650 | | OP_MODIFIES_SOMETHING, | 1650 | | OP_MODIFIES_SOMETHING, |
1651 | .op_name = "OP_DESTROY_CLIENTID", | 1651 | .op_name = "OP_DESTROY_CLIENTID", |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1527aaffb00..47e94e33a97 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1962,6 +1962,50 @@ out: | |||
1962 | return status; | 1962 | return status; |
1963 | } | 1963 | } |
1964 | 1964 | ||
1965 | static inline bool has_resources(struct nfs4_client *clp) | ||
1966 | { | ||
1967 | return !list_empty(&clp->cl_openowners) | ||
1968 | || !list_empty(&clp->cl_delegations) | ||
1969 | || !list_empty(&clp->cl_sessions); | ||
1970 | } | ||
1971 | |||
1972 | __be32 | ||
1973 | nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc) | ||
1974 | { | ||
1975 | struct nfs4_client *conf, *unconf, *clp; | ||
1976 | int status = 0; | ||
1977 | |||
1978 | nfs4_lock_state(); | ||
1979 | unconf = find_unconfirmed_client(&dc->clientid); | ||
1980 | conf = find_confirmed_client(&dc->clientid); | ||
1981 | |||
1982 | if (conf) { | ||
1983 | clp = conf; | ||
1984 | |||
1985 | if (!is_client_expired(conf) && has_resources(conf)) { | ||
1986 | status = nfserr_clientid_busy; | ||
1987 | goto out; | ||
1988 | } | ||
1989 | |||
1990 | /* rfc5661 18.50.3 */ | ||
1991 | if (cstate->session && conf == cstate->session->se_client) { | ||
1992 | status = nfserr_clientid_busy; | ||
1993 | goto out; | ||
1994 | } | ||
1995 | } else if (unconf) | ||
1996 | clp = unconf; | ||
1997 | else { | ||
1998 | status = nfserr_stale_clientid; | ||
1999 | goto out; | ||
2000 | } | ||
2001 | |||
2002 | expire_client(clp); | ||
2003 | out: | ||
2004 | nfs4_unlock_state(); | ||
2005 | dprintk("%s return %d\n", __func__, ntohl(status)); | ||
2006 | return status; | ||
2007 | } | ||
2008 | |||
1965 | __be32 | 2009 | __be32 |
1966 | nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) | 2010 | nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) |
1967 | { | 2011 | { |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index decea140b32..66d095d7955 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1417,6 +1417,16 @@ xdr_error: | |||
1417 | goto out; | 1417 | goto out; |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc) | ||
1421 | { | ||
1422 | DECODE_HEAD; | ||
1423 | |||
1424 | READ_BUF(8); | ||
1425 | COPYMEM(&dc->clientid, 8); | ||
1426 | |||
1427 | DECODE_TAIL; | ||
1428 | } | ||
1429 | |||
1420 | static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) | 1430 | static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) |
1421 | { | 1431 | { |
1422 | DECODE_HEAD; | 1432 | DECODE_HEAD; |
@@ -1538,7 +1548,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { | |||
1538 | [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, | 1548 | [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, |
1539 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, | 1549 | [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_test_stateid, |
1540 | [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, | 1550 | [OP_WANT_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp, |
1541 | [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, | 1551 | [OP_DESTROY_CLIENTID] = (nfsd4_dec)nfsd4_decode_destroy_clientid, |
1542 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, | 1552 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, |
1543 | }; | 1553 | }; |
1544 | 1554 | ||
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index e3057350eea..2364747ee97 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -398,6 +398,10 @@ struct nfsd4_destroy_session { | |||
398 | struct nfs4_sessionid sessionid; | 398 | struct nfs4_sessionid sessionid; |
399 | }; | 399 | }; |
400 | 400 | ||
401 | struct nfsd4_destroy_clientid { | ||
402 | clientid_t clientid; | ||
403 | }; | ||
404 | |||
401 | struct nfsd4_reclaim_complete { | 405 | struct nfsd4_reclaim_complete { |
402 | u32 rca_one_fs; | 406 | u32 rca_one_fs; |
403 | }; | 407 | }; |
@@ -552,6 +556,7 @@ extern __be32 nfsd4_sequence(struct svc_rqst *, | |||
552 | extern __be32 nfsd4_destroy_session(struct svc_rqst *, | 556 | extern __be32 nfsd4_destroy_session(struct svc_rqst *, |
553 | struct nfsd4_compound_state *, | 557 | struct nfsd4_compound_state *, |
554 | struct nfsd4_destroy_session *); | 558 | struct nfsd4_destroy_session *); |
559 | extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *); | ||
555 | __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); | 560 | __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); |
556 | extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, | 561 | extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, |
557 | struct nfsd4_open *open); | 562 | struct nfsd4_open *open); |