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 |
