1249592Sken/*-
2249592Sken * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
3249592Sken * Copyright (c) 2013 Spectra Logic Corporation
4249592Sken *
5249592Sken * Redistribution and use in source and binary forms, with or without
6249592Sken * modification, are permitted provided that the following conditions
7249592Sken * are met:
8249592Sken * 1. Redistributions of source code must retain the above copyright
9249592Sken *    notice, this list of conditions and the following disclaimer.
10249592Sken * 2. Redistributions in binary form must reproduce the above copyright
11249592Sken *    notice, this list of conditions and the following disclaimer in the
12249592Sken *    documentation and/or other materials provided with the distribution.
13249592Sken *
14249592Sken * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15249592Sken * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16249592Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17249592Sken * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18249592Sken * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19249592Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20249592Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21249592Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22249592Sken * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23249592Sken * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24249592Sken * SUCH DAMAGE.
25249592Sken */
26249592Sken
27249592Sken#include <sys/cdefs.h>
28249592Sken__FBSDID("$FreeBSD$");
29249592Sken
30249592Sken#include <sys/param.h>
31249592Sken#include <sys/systm.h>
32249592Sken#include <sys/sysproto.h>
33249592Sken#include <sys/kernel.h>
34249592Sken#include <sys/vnode.h>
35249592Sken#include <sys/malloc.h>
36249592Sken#include <sys/mount.h>
37249592Sken#include <sys/mbuf.h>
38249592Sken#include <sys/sysctl.h>
39249592Sken
40249592Sken#include <rpc/rpc.h>
41249592Sken#include <nfs/xdr_subs.h>
42249592Sken#include <nfs/nfsproto.h>
43249596Sken#include <nfs/nfs_fha.h>
44249592Sken#include <nfsserver/nfs.h>
45249592Sken#include <nfsserver/nfsm_subs.h>
46249592Sken#include <nfsserver/nfs_fha_old.h>
47249592Sken
48249592Skenstatic void fhaold_init(void *foo);
49249592Skenstatic void fhaold_uninit(void *foo);
50249592Skenrpcproc_t fhaold_get_procnum(rpcproc_t procnum);
51249592Skenint fhaold_realign(struct mbuf **mb, int malloc_flags);
52249592Skenint fhaold_get_fh(fhandle_t *fh, int v3, struct mbuf **md, caddr_t *dpos);
53249592Skenint fhaold_is_read(rpcproc_t procnum);
54249592Skenint fhaold_is_write(rpcproc_t procnum);
55249592Skenint fhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3,
56249592Sken		      struct fha_info *info);
57249592Skenint fhaold_no_offset(rpcproc_t procnum);
58249592Skenvoid fhaold_set_locktype(rpcproc_t procnum, struct fha_info *info);
59249592Skenstatic int fheold_stats_sysctl(SYSCTL_HANDLER_ARGS);
60249592Sken
61249592Skenstatic struct fha_params fhaold_softc;
62249592Sken
63249592SkenSYSCTL_DECL(_vfs_nfsrv);
64249592Sken
65249592Skenextern SVCPOOL *nfsrv_pool;
66249592Sken
67249592SkenSYSINIT(nfs_fhaold, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhaold_init, NULL);
68249592SkenSYSUNINIT(nfs_fhaold, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhaold_uninit, NULL);
69249592Sken
70249592Skenstatic void
71249592Skenfhaold_init(void *foo)
72249592Sken{
73249592Sken	struct fha_params *softc;
74249592Sken
75249592Sken	softc = &fhaold_softc;
76249592Sken
77249592Sken	bzero(softc, sizeof(*softc));
78249592Sken
79249592Sken	/*
80249592Sken	 * Setup the callbacks for this FHA personality.
81249592Sken	 */
82249592Sken	softc->callbacks.get_procnum = fhaold_get_procnum;
83249592Sken	softc->callbacks.realign = fhaold_realign;
84249592Sken	softc->callbacks.get_fh = fhaold_get_fh;
85249592Sken	softc->callbacks.is_read = fhaold_is_read;
86249592Sken	softc->callbacks.is_write = fhaold_is_write;
87249592Sken	softc->callbacks.get_offset = fhaold_get_offset;
88249592Sken	softc->callbacks.no_offset = fhaold_no_offset;
89249592Sken	softc->callbacks.set_locktype = fhaold_set_locktype;
90249592Sken	softc->callbacks.fhe_stats_sysctl = fheold_stats_sysctl;
91249592Sken
92249592Sken	snprintf(softc->server_name, sizeof(softc->server_name),
93249592Sken	    FHAOLD_SERVER_NAME);
94249592Sken
95249592Sken	softc->pool = &nfsrv_pool;
96249592Sken
97249592Sken	/*
98249592Sken	 * Initialize the sysctl context list for the fha module.
99249592Sken	 */
100249592Sken	sysctl_ctx_init(&softc->sysctl_ctx);
101249592Sken	softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
102249592Sken	    SYSCTL_STATIC_CHILDREN(_vfs_nfsrv), OID_AUTO, "fha", CTLFLAG_RD,
103249592Sken	    0, "fha node");
104249592Sken	if (softc->sysctl_tree == NULL) {
105249592Sken		printf("%s: unable to allocate sysctl tree\n", __func__);
106249592Sken		return;
107249592Sken	}
108249592Sken	fha_init(softc);
109249592Sken}
110249592Sken
111249592Skenstatic void
112249592Skenfhaold_uninit(void *foo)
113249592Sken{
114249592Sken	struct fha_params *softc;
115249592Sken
116249592Sken	softc = &fhaold_softc;
117249592Sken
118249592Sken	fha_uninit(softc);
119249592Sken}
120249592Sken
121249592Sken
122249592Skenrpcproc_t
123249592Skenfhaold_get_procnum(rpcproc_t procnum)
124249592Sken{
125249592Sken	if (procnum > NFSV2PROC_STATFS)
126249592Sken		return (-1);
127249592Sken
128249592Sken	return (nfsrv_nfsv3_procid[procnum]);
129249592Sken}
130249592Sken
131249592Skenint
132249592Skenfhaold_realign(struct mbuf **mb, int malloc_flags)
133249592Sken{
134249592Sken	return (nfs_realign(mb, malloc_flags));
135249592Sken}
136249592Sken
137249592Skenint
138249592Skenfhaold_get_fh(fhandle_t *fh, int v3, struct mbuf **md, caddr_t *dpos)
139249592Sken{
140249592Sken	return (nfsm_srvmtofh_xx(fh, v3, md, dpos));
141249592Sken}
142249592Sken
143249592Skenint
144249592Skenfhaold_is_read(rpcproc_t procnum)
145249592Sken{
146249592Sken	if (procnum == NFSPROC_READ)
147249592Sken		return (1);
148249592Sken	else
149249592Sken		return (0);
150249592Sken}
151249592Sken
152249592Skenint
153249592Skenfhaold_is_write(rpcproc_t procnum)
154249592Sken{
155249592Sken	if (procnum == NFSPROC_WRITE)
156249592Sken		return (1);
157249592Sken	else
158249592Sken		return (0);
159249592Sken}
160249592Sken
161249592Skenint
162249592Skenfhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3,
163249592Sken		  struct fha_info *info)
164249592Sken{
165249592Sken	uint32_t *tl;
166249592Sken
167249592Sken	if (v3) {
168249592Sken		tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos);
169249592Sken		if (tl == NULL)
170249592Sken			goto out;
171249592Sken		info->offset = fxdr_hyper(tl);
172249592Sken	} else {
173249592Sken		tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
174249592Sken		if (tl == NULL)
175249592Sken			goto out;
176249592Sken		info->offset = fxdr_unsigned(uint32_t, *tl);
177249592Sken	}
178249592Sken
179249592Sken	return (0);
180249592Skenout:
181249592Sken	return (-1);
182249592Sken}
183249592Sken
184249592Skenint
185249592Skenfhaold_no_offset(rpcproc_t procnum)
186249592Sken{
187249592Sken	if (procnum == NFSPROC_FSSTAT ||
188249592Sken	    procnum == NFSPROC_FSINFO ||
189249592Sken	    procnum == NFSPROC_PATHCONF ||
190249592Sken	    procnum == NFSPROC_NOOP ||
191249592Sken	    procnum == NFSPROC_NULL)
192249592Sken		return (1);
193249592Sken	else
194249592Sken		return (0);
195249592Sken}
196249592Sken
197249592Skenvoid
198249592Skenfhaold_set_locktype(rpcproc_t procnum, struct fha_info *info)
199249592Sken{
200249592Sken	switch (procnum) {
201249592Sken	case NFSPROC_NULL:
202249592Sken	case NFSPROC_GETATTR:
203249592Sken	case NFSPROC_LOOKUP:
204249592Sken	case NFSPROC_ACCESS:
205249592Sken	case NFSPROC_READLINK:
206249592Sken	case NFSPROC_READ:
207249592Sken	case NFSPROC_READDIR:
208249592Sken	case NFSPROC_READDIRPLUS:
209249592Sken	case NFSPROC_WRITE:
210249592Sken		info->locktype = LK_SHARED;
211249592Sken		break;
212249592Sken	case NFSPROC_SETATTR:
213249592Sken	case NFSPROC_CREATE:
214249592Sken	case NFSPROC_MKDIR:
215249592Sken	case NFSPROC_SYMLINK:
216249592Sken	case NFSPROC_MKNOD:
217249592Sken	case NFSPROC_REMOVE:
218249592Sken	case NFSPROC_RMDIR:
219249592Sken	case NFSPROC_RENAME:
220249592Sken	case NFSPROC_LINK:
221249592Sken	case NFSPROC_FSSTAT:
222249592Sken	case NFSPROC_FSINFO:
223249592Sken	case NFSPROC_PATHCONF:
224249592Sken	case NFSPROC_COMMIT:
225249592Sken	case NFSPROC_NOOP:
226249592Sken		info->locktype = LK_EXCLUSIVE;
227249592Sken		break;
228249592Sken	}
229249592Sken}
230249592Sken
231249592Skenstatic int
232249592Skenfheold_stats_sysctl(SYSCTL_HANDLER_ARGS)
233249592Sken{
234249592Sken	return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhaold_softc));
235249592Sken}
236249592Sken
237249592SkenSVCTHREAD *
238249592Skenfhaold_assign(SVCTHREAD *this_thread, struct svc_req *req)
239249592Sken{
240249592Sken	return (fha_assign(this_thread, req, &fhaold_softc));
241249592Sken}
242