aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2009-09-10 05:25:59 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-09-15 20:49:55 -0400
commit38524ab38f2752beee262a97403d871665838172 (patch)
treecbccd7de004d2ad437bd514fc3baefefd6a711f5 /fs/nfsd
parent80fc015bdfe1f5b870c1e1ee02d78e709523fee7 (diff)
nfsd41: Backchannel: callback infrastructure
Keep the xprt used for create_session in cl_cb_xprt. Mark cl_callback.cb_minorversion = 1 and remember the client provided cl_callback.cb_prog rpc program number. Use it to probe the callback path. Use the client's network address to initialize as the callback's address as expected by the xprt creation routines. Define xdr sizes and code nfs4_cb_compound header to be able to send a null callback rpc. Signed-off-by: Andy Adamson<andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Ricardo Labiaga <Ricardo.Labiaga@netapp.com> [get callback minorversion from fore channel's] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfsd41: change bc_sock to bc_xprt] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [pulled definition for cl_cb_xprt] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfsd41: set up backchannel's cb_addr] [moved rpc_create_args init to "nfsd: modify nfsd4.1 backchannel to use new xprt class"] Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4callback.c17
-rw-r--r--fs/nfsd/nfs4state.c14
2 files changed, 29 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 128519769ea8..db4188ce9b00 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -43,6 +43,7 @@
43#include <linux/sunrpc/xdr.h> 43#include <linux/sunrpc/xdr.h>
44#include <linux/sunrpc/svc.h> 44#include <linux/sunrpc/svc.h>
45#include <linux/sunrpc/clnt.h> 45#include <linux/sunrpc/clnt.h>
46#include <linux/sunrpc/svcsock.h>
46#include <linux/nfsd/nfsd.h> 47#include <linux/nfsd/nfsd.h>
47#include <linux/nfsd/state.h> 48#include <linux/nfsd/state.h>
48#include <linux/sunrpc/sched.h> 49#include <linux/sunrpc/sched.h>
@@ -52,16 +53,19 @@
52 53
53#define NFSPROC4_CB_NULL 0 54#define NFSPROC4_CB_NULL 0
54#define NFSPROC4_CB_COMPOUND 1 55#define NFSPROC4_CB_COMPOUND 1
56#define NFS4_STATEID_SIZE 16
55 57
56/* Index of predefined Linux callback client operations */ 58/* Index of predefined Linux callback client operations */
57 59
58enum { 60enum {
59 NFSPROC4_CLNT_CB_NULL = 0, 61 NFSPROC4_CLNT_CB_NULL = 0,
60 NFSPROC4_CLNT_CB_RECALL, 62 NFSPROC4_CLNT_CB_RECALL,
63 NFSPROC4_CLNT_CB_SEQUENCE,
61}; 64};
62 65
63enum nfs_cb_opnum4 { 66enum nfs_cb_opnum4 {
64 OP_CB_RECALL = 4, 67 OP_CB_RECALL = 4,
68 OP_CB_SEQUENCE = 11,
65}; 69};
66 70
67#define NFS4_MAXTAGLEN 20 71#define NFS4_MAXTAGLEN 20
@@ -70,15 +74,22 @@ enum nfs_cb_opnum4 {
70#define NFS4_dec_cb_null_sz 0 74#define NFS4_dec_cb_null_sz 0
71#define cb_compound_enc_hdr_sz 4 75#define cb_compound_enc_hdr_sz 4
72#define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2)) 76#define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2))
77#define sessionid_sz (NFS4_MAX_SESSIONID_LEN >> 2)
78#define cb_sequence_enc_sz (sessionid_sz + 4 + \
79 1 /* no referring calls list yet */)
80#define cb_sequence_dec_sz (op_dec_sz + sessionid_sz + 4)
81
73#define op_enc_sz 1 82#define op_enc_sz 1
74#define op_dec_sz 2 83#define op_dec_sz 2
75#define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2)) 84#define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2))
76#define enc_stateid_sz (NFS4_STATEID_SIZE >> 2) 85#define enc_stateid_sz (NFS4_STATEID_SIZE >> 2)
77#define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \ 86#define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \
87 cb_sequence_enc_sz + \
78 1 + enc_stateid_sz + \ 88 1 + enc_stateid_sz + \
79 enc_nfs4_fh_sz) 89 enc_nfs4_fh_sz)
80 90
81#define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \ 91#define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \
92 cb_sequence_dec_sz + \
82 op_dec_sz) 93 op_dec_sz)
83 94
84/* 95/*
@@ -137,11 +148,13 @@ xdr_error: \
137} while (0) 148} while (0)
138 149
139struct nfs4_cb_compound_hdr { 150struct nfs4_cb_compound_hdr {
140 int status; 151 /* args */
141 u32 ident; 152 u32 ident; /* minorversion 0 only */
142 u32 nops; 153 u32 nops;
143 __be32 *nops_p; 154 __be32 *nops_p;
144 u32 minorversion; 155 u32 minorversion;
156 /* res */
157 int status;
145 u32 taglen; 158 u32 taglen;
146 char *tag; 159 char *tag;
147}; 160};
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 0445192d660d..d8196b453f61 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -702,6 +702,8 @@ static inline void
702free_client(struct nfs4_client *clp) 702free_client(struct nfs4_client *clp)
703{ 703{
704 shutdown_callback_client(clp); 704 shutdown_callback_client(clp);
705 if (clp->cl_cb_xprt)
706 svc_xprt_put(clp->cl_cb_xprt);
705 if (clp->cl_cred.cr_group_info) 707 if (clp->cl_cred.cr_group_info)
706 put_group_info(clp->cl_cred.cr_group_info); 708 put_group_info(clp->cl_cred.cr_group_info);
707 kfree(clp->cl_principal); 709 kfree(clp->cl_principal);
@@ -1317,6 +1319,18 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1317 cr_ses->flags &= ~SESSION4_PERSIST; 1319 cr_ses->flags &= ~SESSION4_PERSIST;
1318 cr_ses->flags &= ~SESSION4_RDMA; 1320 cr_ses->flags &= ~SESSION4_RDMA;
1319 1321
1322 if (cr_ses->flags & SESSION4_BACK_CHAN) {
1323 unconf->cl_cb_xprt = rqstp->rq_xprt;
1324 svc_xprt_get(unconf->cl_cb_xprt);
1325 rpc_copy_addr(
1326 (struct sockaddr *)&unconf->cl_cb_conn.cb_addr,
1327 sa);
1328 unconf->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
1329 unconf->cl_cb_conn.cb_minorversion =
1330 cstate->minorversion;
1331 unconf->cl_cb_conn.cb_prog = cr_ses->callback_prog;
1332 nfsd4_probe_callback(unconf);
1333 }
1320 conf = unconf; 1334 conf = unconf;
1321 } else { 1335 } else {
1322 status = nfserr_stale_clientid; 1336 status = nfserr_stale_clientid;