nfs_fha_new.c revision 249596
118334Speter/*-
218334Speter * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
318334Speter * Copyright (c) 2013 Spectra Logic Corporation
418334Speter *
518334Speter * Redistribution and use in source and binary forms, with or without
618334Speter * modification, are permitted provided that the following conditions
718334Speter * are met:
818334Speter * 1. Redistributions of source code must retain the above copyright
918334Speter *    notice, this list of conditions and the following disclaimer.
1018334Speter * 2. Redistributions in binary form must reproduce the above copyright
1118334Speter *    notice, this list of conditions and the following disclaimer in the
1218334Speter *    documentation and/or other materials provided with the distribution.
1318334Speter *
1418334Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1518334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1618334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1718334Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1818334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1918334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2018334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2118334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2218334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2318334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2418334Speter * SUCH DAMAGE.
2518334Speter */
2618334Speter
2718334Speter#include <sys/cdefs.h>
2818334Speter__FBSDID("$FreeBSD: head/sys/fs/nfsserver/nfs_fha_new.c 249596 2013-04-17 22:42:43Z ken $");
2918334Speter
3018334Speter#include <fs/nfs/nfsport.h>
3118334Speter
3218334Speter#include <rpc/rpc.h>
3318334Speter#include <nfs/nfs_fha.h>
3418334Speter#include <fs/nfs/xdr_subs.h>
3518334Speter#include <fs/nfs/nfs.h>
3618334Speter#include <fs/nfs/nfsproto.h>
3718334Speter#include <fs/nfs/nfsm_subs.h>
3818334Speter#include <fs/nfsserver/nfs_fha_new.h>
3918334Speter
4018334Speterstatic void fhanew_init(void *foo);
4118334Speterstatic void fhanew_uninit(void *foo);
4218334Speterrpcproc_t fhanew_get_procnum(rpcproc_t procnum);
4318334Speterint fhanew_realign(struct mbuf **mb, int malloc_flags);
4418334Speterint fhanew_get_fh(fhandle_t *fh, int v3, struct mbuf **md, caddr_t *dpos);
4518334Speterint fhanew_is_read(rpcproc_t procnum);
4618334Speterint fhanew_is_write(rpcproc_t procnum);
4718334Speterint fhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3,
4818334Speter		      struct fha_info *info);
4918334Speterint fhanew_no_offset(rpcproc_t procnum);
5018334Spetervoid fhanew_set_locktype(rpcproc_t procnum, struct fha_info *info);
5118334Speterstatic int fhenew_stats_sysctl(SYSCTL_HANDLER_ARGS);
5218334Speter
5318334Speterstatic struct fha_params fhanew_softc;
5418334Speter
5518334SpeterSYSCTL_DECL(_vfs_nfsd);
5618334Speter
5718334Speterextern int newnfs_nfsv3_procid[];
5818334Speterextern SVCPOOL	*nfsrvd_pool;
5918334Speter
6018334SpeterSYSINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_init, NULL);
6118334SpeterSYSUNINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_uninit, NULL);
6218334Speter
6318334Speterstatic void
6418334Speterfhanew_init(void *foo)
6518334Speter{
6618334Speter	struct fha_params *softc;
6718334Speter
6850397Sobrien	softc = &fhanew_softc;
6918334Speter
7018334Speter	bzero(softc, sizeof(*softc));
7118334Speter
7218334Speter	/*
7318334Speter	 * Setup the callbacks for this FHA personality.
7418334Speter	 */
7518334Speter	softc->callbacks.get_procnum = fhanew_get_procnum;
7618334Speter	softc->callbacks.realign = fhanew_realign;
7718334Speter	softc->callbacks.get_fh = fhanew_get_fh;
7818334Speter	softc->callbacks.is_read = fhanew_is_read;
7918334Speter	softc->callbacks.is_write = fhanew_is_write;
8018334Speter	softc->callbacks.get_offset = fhanew_get_offset;
8118334Speter	softc->callbacks.no_offset = fhanew_no_offset;
8218334Speter	softc->callbacks.set_locktype = fhanew_set_locktype;
8318334Speter	softc->callbacks.fhe_stats_sysctl = fhenew_stats_sysctl;
8418334Speter
8518334Speter	snprintf(softc->server_name, sizeof(softc->server_name),
8618334Speter	    FHANEW_SERVER_NAME);
8718334Speter
8818334Speter	softc->pool = &nfsrvd_pool;
8918334Speter
9018334Speter	/*
9118334Speter	 * Initialize the sysctl context list for the fha module.
9218334Speter	 */
9318334Speter	sysctl_ctx_init(&softc->sysctl_ctx);
9418334Speter	softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
9518334Speter	    SYSCTL_STATIC_CHILDREN(_vfs_nfsd), OID_AUTO, "fha", CTLFLAG_RD,
9618334Speter	    0, "fha node");
9718334Speter	if (softc->sysctl_tree == NULL) {
9818334Speter		printf("%s: unable to allocate sysctl tree\n", __func__);
9918334Speter		return;
10018334Speter	}
10118334Speter
10218334Speter	fha_init(softc);
10318334Speter}
10418334Speter
10518334Speterstatic void
10618334Speterfhanew_uninit(void *foo)
10718334Speter{
10818334Speter	struct fha_params *softc;
10918334Speter
11018334Speter	softc = &fhanew_softc;
11118334Speter
11218334Speter	fha_uninit(softc);
11318334Speter}
11418334Speter
11518334Speterrpcproc_t
11618334Speterfhanew_get_procnum(rpcproc_t procnum)
11718334Speter{
11818334Speter	if (procnum > NFSV2PROC_STATFS)
11918334Speter		return (-1);
12018334Speter
12118334Speter	return (newnfs_nfsv3_procid[procnum]);
12218334Speter}
12350397Sobrien
12418334Speterint
12518334Speterfhanew_realign(struct mbuf **mb, int malloc_flags)
12618334Speter{
12718334Speter	return (newnfs_realign(mb, malloc_flags));
12818334Speter}
12918334Speter
13018334Speterint
13118334Speterfhanew_get_fh(fhandle_t *fh, int v3, struct mbuf **md, caddr_t *dpos)
13218334Speter{
13318334Speter	struct nfsrv_descript lnd, *nd;
13418334Speter	uint32_t *tl;
13518334Speter	int error, len;
13618334Speter
13718334Speter	error = 0;
13818334Speter	len = 0;
13918334Speter	nd = &lnd;
14018334Speter
14118334Speter	nd->nd_md = *md;
14218334Speter	nd->nd_dpos = *dpos;
14318334Speter
14418334Speter	if (v3) {
14518334Speter		NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED);
14650397Sobrien		if ((len = fxdr_unsigned(int, *tl)) <= 0 || len > NFSX_FHMAX) {
14718334Speter			error = EBADRPC;
14818334Speter			goto nfsmout;
14918334Speter		}
15018334Speter	} else {
15118334Speter		len = NFSX_V2FH;
15218334Speter	}
15318334Speter
15418334Speter	if (len != 0) {
15518334Speter		NFSM_DISSECT_NONBLOCK(tl, uint32_t *, len);
15618334Speter		bcopy(tl, fh, len);
15718334Speter	} else
15818334Speter		bzero(fh, sizeof(*fh));
15918334Speter
16018334Speternfsmout:
16118334Speter	*md = nd->nd_md;
16218334Speter	*dpos = nd->nd_dpos;
16318334Speter
16418334Speter	return (error);
16518334Speter}
16618334Speter
16718334Speterint
16818334Speterfhanew_is_read(rpcproc_t procnum)
16918334Speter{
17018334Speter	if (procnum == NFSPROC_READ)
17118334Speter		return (1);
17218334Speter	else
17318334Speter		return (0);
17418334Speter}
17518334Speter
17618334Speterint
17718334Speterfhanew_is_write(rpcproc_t procnum)
17850397Sobrien{
17950397Sobrien	if (procnum == NFSPROC_WRITE)
18050397Sobrien		return (1);
18118334Speter	else
18218334Speter		return (0);
18318334Speter}
18418334Speter
18518334Speterint
18618334Speterfhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3,
18718334Speter		  struct fha_info *info)
18818334Speter{
18918334Speter	struct nfsrv_descript lnd, *nd;
19018334Speter	uint32_t *tl;
19118334Speter	int error;
19218334Speter
19318334Speter	error = 0;
19418334Speter
19518334Speter	nd = &lnd;
19618334Speter	nd->nd_md = *md;
19718334Speter	nd->nd_dpos = *dpos;
19818334Speter
19918334Speter	if (v3) {
20018334Speter		NFSM_DISSECT_NONBLOCK(tl, uint32_t *, 2 * NFSX_UNSIGNED);
20118334Speter		info->offset = fxdr_hyper(tl);
20218334Speter	} else {
20318334Speter		NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED);
20418334Speter		info->offset = fxdr_unsigned(uint32_t, *tl);
20550397Sobrien	}
20650397Sobrien
20750397Sobriennfsmout:
20818334Speter	*md = nd->nd_md;
20918334Speter	*dpos = nd->nd_dpos;
21018334Speter
21118334Speter	return (error);
21218334Speter}
21318334Speter
21418334Speterint
21518334Speterfhanew_no_offset(rpcproc_t procnum)
21618334Speter{
21718334Speter	if (procnum == NFSPROC_FSSTAT ||
21818334Speter	    procnum == NFSPROC_FSINFO ||
21918334Speter	    procnum == NFSPROC_PATHCONF ||
22018334Speter	    procnum == NFSPROC_NOOP ||
22118334Speter	    procnum == NFSPROC_NULL)
22218334Speter		return (1);
22318334Speter	else
22418334Speter		return (0);
22518334Speter}
22618334Speter
22718334Spetervoid
22818334Speterfhanew_set_locktype(rpcproc_t procnum, struct fha_info *info)
22918334Speter{
23018334Speter	switch (procnum) {
23118334Speter	case NFSPROC_NULL:
23218334Speter	case NFSPROC_GETATTR:
23318334Speter	case NFSPROC_LOOKUP:
23418334Speter	case NFSPROC_ACCESS:
23518334Speter	case NFSPROC_READLINK:
23618334Speter	case NFSPROC_READ:
23718334Speter	case NFSPROC_READDIR:
23818334Speter	case NFSPROC_READDIRPLUS:
23918334Speter	case NFSPROC_WRITE:
24018334Speter		info->locktype = LK_SHARED;
24118334Speter		break;
24218334Speter	case NFSPROC_SETATTR:
24318334Speter	case NFSPROC_CREATE:
24418334Speter	case NFSPROC_MKDIR:
24518334Speter	case NFSPROC_SYMLINK:
24618334Speter	case NFSPROC_MKNOD:
24718334Speter	case NFSPROC_REMOVE:
24818334Speter	case NFSPROC_RMDIR:
24918334Speter	case NFSPROC_RENAME:
25018334Speter	case NFSPROC_LINK:
25118334Speter	case NFSPROC_FSSTAT:
25218334Speter	case NFSPROC_FSINFO:
25318334Speter	case NFSPROC_PATHCONF:
25418334Speter	case NFSPROC_COMMIT:
25518334Speter	case NFSPROC_NOOP:
25618334Speter		info->locktype = LK_EXCLUSIVE;
25718334Speter		break;
25818334Speter	}
25918334Speter}
26018334Speter
26118334Speterstatic int
26218334Speterfhenew_stats_sysctl(SYSCTL_HANDLER_ARGS)
26318334Speter{
26418334Speter	return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhanew_softc));
26518334Speter}
26618334Speter
26718334Speter
26818334SpeterSVCTHREAD *
26918334Speterfhanew_assign(SVCTHREAD *this_thread, struct svc_req *req)
27050397Sobrien{
27150397Sobrien	return (fha_assign(this_thread, req, &fhanew_softc));
27218334Speter}
27350397Sobrien