diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3b4d74cbb6c..596702e157c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -658,13 +658,18 @@ static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp) | |||
658 | return conn; | 658 | return conn; |
659 | } | 659 | } |
660 | 660 | ||
661 | static void __nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) | ||
662 | { | ||
663 | conn->cn_session = ses; | ||
664 | list_add(&conn->cn_persession, &ses->se_conns); | ||
665 | } | ||
666 | |||
661 | static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) | 667 | static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) |
662 | { | 668 | { |
663 | struct nfs4_client *clp = ses->se_client; | 669 | struct nfs4_client *clp = ses->se_client; |
664 | 670 | ||
665 | spin_lock(&clp->cl_lock); | 671 | spin_lock(&clp->cl_lock); |
666 | conn->cn_session = ses; | 672 | __nfsd4_hash_conn(conn, ses); |
667 | list_add(&conn->cn_persession, &ses->se_conns); | ||
668 | spin_unlock(&clp->cl_lock); | 673 | spin_unlock(&clp->cl_lock); |
669 | } | 674 | } |
670 | 675 | ||
@@ -1612,6 +1617,44 @@ out: | |||
1612 | return status; | 1617 | return status; |
1613 | } | 1618 | } |
1614 | 1619 | ||
1620 | static struct nfsd4_conn *__nfsd4_find_conn(struct svc_rqst *r, struct nfsd4_session *s) | ||
1621 | { | ||
1622 | struct nfsd4_conn *c; | ||
1623 | |||
1624 | list_for_each_entry(c, &s->se_conns, cn_persession) { | ||
1625 | if (c->cn_xprt == r->rq_xprt) { | ||
1626 | return c; | ||
1627 | } | ||
1628 | } | ||
1629 | return NULL; | ||
1630 | } | ||
1631 | |||
1632 | static void nfsd4_sequence_check_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) | ||
1633 | { | ||
1634 | struct nfs4_client *clp = ses->se_client; | ||
1635 | struct nfsd4_conn *c, *new = NULL; | ||
1636 | |||
1637 | spin_lock(&clp->cl_lock); | ||
1638 | c = __nfsd4_find_conn(rqstp, ses); | ||
1639 | spin_unlock(&clp->cl_lock); | ||
1640 | if (c) | ||
1641 | return; | ||
1642 | |||
1643 | new = alloc_conn(rqstp); | ||
1644 | |||
1645 | spin_lock(&clp->cl_lock); | ||
1646 | c = __nfsd4_find_conn(rqstp, ses); | ||
1647 | if (c) { | ||
1648 | spin_unlock(&clp->cl_lock); | ||
1649 | free_conn(new); | ||
1650 | return; | ||
1651 | } | ||
1652 | __nfsd4_hash_conn(new, ses); | ||
1653 | spin_unlock(&clp->cl_lock); | ||
1654 | nfsd4_register_conn(new); | ||
1655 | return; | ||
1656 | } | ||
1657 | |||
1615 | __be32 | 1658 | __be32 |
1616 | nfsd4_sequence(struct svc_rqst *rqstp, | 1659 | nfsd4_sequence(struct svc_rqst *rqstp, |
1617 | struct nfsd4_compound_state *cstate, | 1660 | struct nfsd4_compound_state *cstate, |
@@ -1656,6 +1699,8 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
1656 | if (status) | 1699 | if (status) |
1657 | goto out; | 1700 | goto out; |
1658 | 1701 | ||
1702 | nfsd4_sequence_check_conn(rqstp, session); | ||
1703 | |||
1659 | /* Success! bump slot seqid */ | 1704 | /* Success! bump slot seqid */ |
1660 | slot->sl_inuse = true; | 1705 | slot->sl_inuse = true; |
1661 | slot->sl_seqid = seq->seqid; | 1706 | slot->sl_seqid = seq->seqid; |