Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * linux/fs/nfs/callback.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2004 Trond Myklebust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * NFSv4 callback handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/sunrpc/svc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/sunrpc/svcsock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/sunrpc/svcauth_gss.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/sunrpc/bc_xprt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <net/inet_sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "nfs4_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "callback.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define NFSDBG_FACILITY NFSDBG_CALLBACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) struct nfs_callback_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	unsigned int users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct svc_serv *serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static DEFINE_MUTEX(nfs_callback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static struct svc_program nfs4_callback_program;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	const struct cred *cred = current_cred();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct nfs_net *nn = net_generic(net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	ret = svc_create_xprt(serv, "tcp", net, PF_INET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 				cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	nn->nfs_callback_tcpport = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	dprintk("NFS: Callback listener port = %u (af %u, net %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		nn->nfs_callback_tcpport, PF_INET, net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	ret = svc_create_xprt(serv, "tcp", net, PF_INET6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		nn->nfs_callback_tcpport6 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		dprintk("NFS: Callback listener port = %u (af %u, net %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			nn->nfs_callback_tcpport6, PF_INET6, net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	} else if (ret != -EAFNOSUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	return (ret) ? ret : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * This is the NFSv4 callback kernel thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) nfs4_callback_svc(void *vrqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct svc_rqst *rqstp = vrqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	while (!kthread_freezable_should_stop(NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		 * Listen for a request on the socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (err == -EAGAIN || err == -EINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		svc_process(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	svc_exit_thread(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	module_put_and_exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * The callback service for NFSv4.1 callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) nfs41_callback_svc(void *vrqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	struct svc_rqst *rqstp = vrqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct svc_serv *serv = rqstp->rq_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct rpc_rqst *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	DEFINE_WAIT(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	while (!kthread_freezable_should_stop(NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		spin_lock_bh(&serv->sv_cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (!list_empty(&serv->sv_cb_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			req = list_first_entry(&serv->sv_cb_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 					struct rpc_rqst, rq_bc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			list_del(&req->rq_bc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			spin_unlock_bh(&serv->sv_cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			finish_wait(&serv->sv_cb_waitq, &wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			dprintk("Invoking bc_svc_process()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			error = bc_svc_process(serv, req, rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			dprintk("bc_svc_process() returned w/ error code= %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			spin_unlock_bh(&serv->sv_cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			if (!kthread_should_stop())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			finish_wait(&serv->sv_cb_waitq, &wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	svc_exit_thread(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	module_put_and_exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		struct svc_serv *serv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		 * Save the svc_serv in the transport so that it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		 * be referenced when the session backchannel is initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		xprt->bc_serv = serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		struct svc_serv *serv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #endif /* CONFIG_NFS_V4_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				  struct svc_serv *serv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	int nrservs = nfs_callback_nr_threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	nfs_callback_bc_serv(minorversion, xprt, serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (nrservs < NFS4_MIN_NR_CALLBACK_THREADS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		nrservs = NFS4_MIN_NR_CALLBACK_THREADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (serv->sv_nrthreads-1 == nrservs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	ret = serv->sv_ops->svo_setup(serv, NULL, nrservs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		serv->sv_ops->svo_setup(serv, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	dprintk("nfs_callback_up: service started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct nfs_net *nn = net_generic(net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (--nn->cb_users[minorversion])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	dprintk("NFS: destroy per-net callback data; net=%x\n", net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	svc_shutdown_net(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			       struct net *net, struct rpc_xprt *xprt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct nfs_net *nn = net_generic(net, nfs_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (nn->cb_users[minorversion]++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	dprintk("NFS: create per-net callback data; net=%x\n", net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	ret = svc_bind(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		printk(KERN_WARNING "NFS: bind callback service failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		goto err_bind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (!IS_ENABLED(CONFIG_NFS_V4_1) || minorversion == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		ret = nfs4_callback_up_net(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	else if (xprt->ops->bc_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		set_bc_enabled(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		ret = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		printk(KERN_ERR "NFS: callback service start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		goto err_socks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err_socks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	svc_rpcb_cleanup(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) err_bind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	nn->cb_users[minorversion]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	dprintk("NFS: Couldn't create callback socket: err = %d; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			"net = %x\n", ret, net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static const struct svc_serv_ops nfs40_cb_sv_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	.svo_function		= nfs4_callback_svc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	.svo_enqueue_xprt	= svc_xprt_do_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	.svo_setup		= svc_set_num_threads_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	.svo_module		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #if defined(CONFIG_NFS_V4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static const struct svc_serv_ops nfs41_cb_sv_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	.svo_function		= nfs41_callback_svc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	.svo_enqueue_xprt	= svc_xprt_do_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	.svo_setup		= svc_set_num_threads_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	.svo_module		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static const struct svc_serv_ops *nfs4_cb_sv_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	[0] = &nfs40_cb_sv_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	[1] = &nfs41_cb_sv_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static const struct svc_serv_ops *nfs4_cb_sv_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	[0] = &nfs40_cb_sv_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	[1] = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static struct svc_serv *nfs_callback_create_svc(int minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	const struct svc_serv_ops *sv_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	struct svc_serv *serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	 * Check whether we're already up and running.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (cb_info->serv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		 * Note: increase service usage, because later in case of error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		 * svc_destroy() will be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		svc_get(cb_info->serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		return cb_info->serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	switch (minorversion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		sv_ops = nfs4_cb_sv_ops[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		sv_ops = nfs4_cb_sv_ops[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (sv_ops == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		return ERR_PTR(-ENOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	 * Sanity check: if there's no task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	 * we should be the first user ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (cb_info->users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			cb_info->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	serv = svc_create_pooled(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, sv_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (!serv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	cb_info->serv = serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	/* As there is only one thread we need to over-ride the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	 * default maximum of 80 connections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	serv->sv_maxconn = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	dprintk("nfs_callback_create_svc: service created\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  * Bring up the callback thread if it is not already up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct svc_serv *serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	struct net *net = xprt->xprt_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	mutex_lock(&nfs_callback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	serv = nfs_callback_create_svc(minorversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (IS_ERR(serv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		ret = PTR_ERR(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		goto err_create;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	ret = nfs_callback_up_net(minorversion, serv, net, xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		goto err_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	ret = nfs_callback_start_svc(minorversion, xprt, serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		goto err_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	cb_info->users++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	 * svc_create creates the svc_serv with sv_nrthreads == 1, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	 * svc_prepare_thread increments that. So we need to call svc_destroy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	 * on both success and failure so that the refcount is 1 when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	 * thread exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) err_net:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (!cb_info->users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		cb_info->serv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	svc_destroy(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) err_create:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	mutex_unlock(&nfs_callback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) err_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	nfs_callback_down_net(minorversion, serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	dprintk("NFS: Couldn't create server thread; err = %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	goto err_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * Kill the callback thread if it's no longer being used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) void nfs_callback_down(int minorversion, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct svc_serv *serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	mutex_lock(&nfs_callback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	serv = cb_info->serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	nfs_callback_down_net(minorversion, serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	cb_info->users--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	if (cb_info->users == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		svc_get(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		serv->sv_ops->svo_setup(serv, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		svc_destroy(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		dprintk("nfs_callback_down: service destroyed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		cb_info->serv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	mutex_unlock(&nfs_callback_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Boolean check of RPC_AUTH_GSS principal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	char *p = rqstp->rq_cred.cr_principal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	if (rqstp->rq_authop->flavour != RPC_AUTH_GSS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	/* No RPC_AUTH_GSS on NFSv4.1 back channel yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (clp->cl_minorversion != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	 * It might just be a normal user principal, in which case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	 * userspace won't bother to tell us the name at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	 * Did we get the acceptor from userland during the SETCLIENID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	 * negotiation?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (clp->cl_acceptor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		return !strcmp(p, clp->cl_acceptor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	 * Otherwise try to verify it using the cl_hostname. Note that this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	 * doesn't work if a non-canonical hostname was used in the devname.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	/* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	if (memcmp(p, "nfs@", 4) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	p += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (strcmp(p, clp->cl_hostname) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  * pg_authenticate method for nfsv4 callback threads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * The authflavor has been negotiated, so an incorrect flavor is a server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  * bug. Deny packets with incorrect authflavor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  * All other checking done after NFS decoding where the nfs_client can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  * found in nfs4_callback_compound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int nfs_callback_authenticate(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	switch (rqstp->rq_authop->flavour) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	case RPC_AUTH_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		if (rqstp->rq_proc != CB_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			return SVC_DENIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	case RPC_AUTH_GSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		/* No RPC_AUTH_GSS support yet in NFSv4.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		 if (svc_is_backchannel(rqstp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			return SVC_DENIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	return SVC_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)  * Define NFS4 callback program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static const struct svc_version *nfs4_callback_version[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	[1] = &nfs4_callback_version1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	[4] = &nfs4_callback_version4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static struct svc_stat nfs4_callback_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static struct svc_program nfs4_callback_program = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	.pg_prog = NFS4_CALLBACK,			/* RPC service number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	.pg_nvers = ARRAY_SIZE(nfs4_callback_version),	/* Number of entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	.pg_vers = nfs4_callback_version,		/* version table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	.pg_name = "NFSv4 callback",			/* service name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	.pg_class = "nfs",				/* authentication class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	.pg_stats = &nfs4_callback_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	.pg_authenticate = nfs_callback_authenticate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	.pg_init_request = svc_generic_init_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	.pg_rpcbind_set	= svc_generic_rpcbind_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) };