diff options
-rw-r--r-- | fs/nfsd/nfs4callback.c | 17 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 14 | ||||
-rw-r--r-- | include/linux/nfsd/state.h | 3 |
3 files changed, 32 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 | ||
58 | enum { | 60 | enum { |
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 | ||
63 | enum nfs_cb_opnum4 { | 66 | enum 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 | ||
139 | struct nfs4_cb_compound_hdr { | 150 | struct 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 | |||
702 | free_client(struct nfs4_client *clp) | 702 | free_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; |
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index 9bf3aa8c5aea..c916032570c4 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h | |||
@@ -211,6 +211,9 @@ struct nfs4_client { | |||
211 | struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ | 211 | struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ |
212 | u32 cl_exchange_flags; | 212 | u32 cl_exchange_flags; |
213 | struct nfs4_sessionid cl_sessionid; | 213 | struct nfs4_sessionid cl_sessionid; |
214 | |||
215 | /* for nfs41 callbacks */ | ||
216 | struct svc_xprt *cl_cb_xprt; /* 4.1 callback transport */ | ||
214 | }; | 217 | }; |
215 | 218 | ||
216 | /* struct nfs4_client_reset | 219 | /* struct nfs4_client_reset |