@@ -1032,39 +1032,14 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
10321032 PROC (CB_GETATTR , COMPOUND , cb_getattr , cb_getattr ),
10331033};
10341034
1035- static unsigned int nfs4_cb_counts [ARRAY_SIZE (nfs4_cb_procedures )];
1036- static const struct rpc_version nfs_cb_version4 = {
1037- /*
1038- * Note on the callback rpc program version number: despite language in rfc
1039- * 5661 section 18.36.3 requiring servers to use 4 in this field, the
1040- * official xdr descriptions for both 4.0 and 4.1 specify version 1, and
1041- * in practice that appears to be what implementations use. The section
1042- * 18.36.3 language is expected to be fixed in an erratum.
1043- */
1044- .number = 1 ,
1045- .nrprocs = ARRAY_SIZE (nfs4_cb_procedures ),
1046- .procs = nfs4_cb_procedures ,
1047- .counts = nfs4_cb_counts ,
1048- };
1049-
1050- static const struct rpc_version * nfs_cb_version [2 ] = {
1051- [1 ] = & nfs_cb_version4 ,
1052- };
1053-
1054- static const struct rpc_program cb_program ;
1055-
1056- static struct rpc_stat cb_stats = {
1057- .program = & cb_program
1058- };
1059-
1060- #define NFS4_CALLBACK 0x40000000
1061- static const struct rpc_program cb_program = {
1062- .name = "nfs4_cb" ,
1063- .number = NFS4_CALLBACK ,
1064- .nrvers = ARRAY_SIZE (nfs_cb_version ),
1065- .version = nfs_cb_version ,
1066- .stats = & cb_stats ,
1067- .pipe_dir_name = "nfsd4_cb" ,
1035+ #define NFS4_CB_PROGRAM 0x40000000
1036+ #define NFS4_CB_VERSION 1
1037+
1038+ struct nfsd_net_cb {
1039+ struct rpc_version version4 ;
1040+ const struct rpc_version * versions [NFS4_CB_VERSION + 1 ];
1041+ struct rpc_program program ;
1042+ struct rpc_stat stat ;
10681043};
10691044
10701045static int max_cb_time (struct net * net )
@@ -1140,6 +1115,7 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r
11401115
11411116static int setup_callback_client (struct nfs4_client * clp , struct nfs4_cb_conn * conn , struct nfsd4_session * ses )
11421117{
1118+ struct nfsd_net * nn = net_generic (clp -> net , nfsd_net_id );
11431119 int maxtime = max_cb_time (clp -> net );
11441120 struct rpc_timeout timeparms = {
11451121 .to_initval = maxtime ,
@@ -1152,14 +1128,14 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
11521128 .addrsize = conn -> cb_addrlen ,
11531129 .saddress = (struct sockaddr * ) & conn -> cb_saddr ,
11541130 .timeout = & timeparms ,
1155- .program = & cb_program ,
1156- .version = 1 ,
1131+ .version = NFS4_CB_VERSION ,
11571132 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET ),
11581133 .cred = current_cred (),
11591134 };
11601135 struct rpc_clnt * client ;
11611136 const struct cred * cred ;
11621137
1138+ args .program = & nn -> nfsd_cb -> program ;
11631139 if (clp -> cl_minorversion == 0 ) {
11641140 if (!clp -> cl_cred .cr_principal &&
11651141 (clp -> cl_cred .cr_flavor >= RPC_AUTH_GSS_KRB5 )) {
@@ -1786,3 +1762,70 @@ bool nfsd4_run_cb(struct nfsd4_callback *cb)
17861762 nfsd41_cb_inflight_end (clp );
17871763 return queued ;
17881764}
1765+
1766+ /**
1767+ * nfsd_net_cb_shutdown - release per-netns callback RPC program resources
1768+ * @nn: NFS server network namespace
1769+ *
1770+ * Frees resources allocated by nfsd_net_cb_init().
1771+ */
1772+ void nfsd_net_cb_shutdown (struct nfsd_net * nn )
1773+ {
1774+ struct nfsd_net_cb * cb = nn -> nfsd_cb ;
1775+
1776+ if (cb ) {
1777+ kfree (cb -> version4 .counts );
1778+ kfree (cb );
1779+ nn -> nfsd_cb = NULL ;
1780+ }
1781+ }
1782+
1783+ /**
1784+ * nfsd_net_cb_init - initialize per-netns callback RPC program
1785+ * @nn: NFS server network namespace
1786+ *
1787+ * Sets up the callback RPC program, version table, procedure
1788+ * counts, and statistics structure for @nn. Caller must release
1789+ * these resources using nfsd_net_cb_shutdown().
1790+ *
1791+ * Return: 0 on success, or -ENOMEM if allocation fails.
1792+ */
1793+ int nfsd_net_cb_init (struct nfsd_net * nn )
1794+ {
1795+ struct nfsd_net_cb * cb ;
1796+
1797+ cb = kzalloc (sizeof (* cb ), GFP_KERNEL );
1798+ if (!cb )
1799+ return - ENOMEM ;
1800+
1801+ cb -> version4 .counts = kzalloc_objs (unsigned int ,
1802+ ARRAY_SIZE (nfs4_cb_procedures ), GFP_KERNEL );
1803+ if (!cb -> version4 .counts ) {
1804+ kfree (cb );
1805+ return - ENOMEM ;
1806+ }
1807+ /*
1808+ * Note on the callback rpc program version number: despite language
1809+ * in rfc 5661 section 18.36.3 requiring servers to use 4 in this
1810+ * field, the official xdr descriptions for both 4.0 and 4.1 specify
1811+ * version 1, and in practice that appears to be what implementations
1812+ * use. The section 18.36.3 language is expected to be fixed in an
1813+ * erratum.
1814+ */
1815+ cb -> version4 .number = NFS4_CB_VERSION ;
1816+ cb -> version4 .nrprocs = ARRAY_SIZE (nfs4_cb_procedures );
1817+ cb -> version4 .procs = nfs4_cb_procedures ;
1818+ cb -> versions [NFS4_CB_VERSION ] = & cb -> version4 ;
1819+
1820+ cb -> program .name = "nfs4_cb" ;
1821+ cb -> program .number = NFS4_CB_PROGRAM ;
1822+ cb -> program .nrvers = ARRAY_SIZE (cb -> versions );
1823+ cb -> program .version = & cb -> versions [0 ];
1824+ cb -> program .pipe_dir_name = "nfsd4_cb" ;
1825+ cb -> program .stats = & cb -> stat ;
1826+ cb -> stat .program = & cb -> program ;
1827+
1828+ nn -> nfsd_cb = cb ;
1829+
1830+ return 0 ;
1831+ }
0 commit comments