aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorMi Jinlong <mijinlong@cn.fujitsu.com>2011-10-20 05:51:39 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-10-24 04:24:30 -0400
commit345c284290cabb5484df909303e73d6def8ec8ec (patch)
tree1a853fe648230fefee758e36bd1ab141639c0b83 /fs/nfsd
parent92bac8c5d60623167c6802b1f125e6d623708185 (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.c2
-rw-r--r--fs/nfsd/nfs4state.c44
-rw-r--r--fs/nfsd/nfs4xdr.c12
-rw-r--r--fs/nfsd/xdr4.h5
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
1965static 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
1973nfsd4_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);
2003out:
2004 nfs4_unlock_state();
2005 dprintk("%s return %d\n", __func__, ntohl(status));
2006 return status;
2007}
2008
1965__be32 2009__be32
1966nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) 2010nfsd4_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
1420static __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
1420static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc) 1430static __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
401struct nfsd4_destroy_clientid {
402 clientid_t clientid;
403};
404
401struct nfsd4_reclaim_complete { 405struct 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 *,
552extern __be32 nfsd4_destroy_session(struct svc_rqst *, 556extern __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 *);
559extern __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 *);
556extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, 561extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
557 struct nfsd4_open *open); 562 struct nfsd4_open *open);