12061Sjkh/* $NetBSD: nfs_fha_new.c,v 1.2 2016/12/13 21:50:32 pgoyette Exp $ */ 22834Swollman/*- 32061Sjkh * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 42061Sjkh * Copyright (c) 2013 Spectra Logic Corporation 52061Sjkh * 62061Sjkh * Redistribution and use in source and binary forms, with or without 72061Sjkh * modification, are permitted provided that the following conditions 82061Sjkh * are met: 92160Scsgr * 1. Redistributions of source code must retain the above copyright 102160Scsgr * notice, this list of conditions and the following disclaimer. 112834Swollman * 2. Redistributions in binary form must reproduce the above copyright 122061Sjkh * notice, this list of conditions and the following disclaimer in the 132061Sjkh * documentation and/or other materials provided with the distribution. 142160Scsgr * 152626Scsgr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 162061Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 172160Scsgr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 181594Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 192061Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 202160Scsgr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 212061Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 221594Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 232061Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 242061Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 252061Sjkh * SUCH DAMAGE. 262061Sjkh */ 272061Sjkh 282061Sjkh#include <sys/cdefs.h> 292061Sjkh/* __FBSDID("FreeBSD: head/sys/fs/nfsserver/nfs_fha_new.c 259765 2013-12-23 08:43:16Z mav "); */ 302061Sjkh__RCSID("$NetBSD: nfs_fha_new.c,v 1.2 2016/12/13 21:50:32 pgoyette Exp $"); 312061Sjkh 322061Sjkh#include <fs/nfs/common/nfsport.h> 332061Sjkh 342061Sjkh#include <rpc/rpc.h> 352061Sjkh#include <fs/nfs/common/nfs_fha.h> 362061Sjkh#include <fs/nfs/common/xdr_subs.h> 372061Sjkh#include <fs/nfs/common/nfs.h> 382061Sjkh#include <fs/nfs/common/nfsproto.h> 392061Sjkh#include <fs/nfs/common/nfsm_subs.h> 402061Sjkh#include <fs/nfs/server/nfs_fha_new.h> 412061Sjkh 422061Sjkhstatic void fhanew_init(void *foo); 432061Sjkhstatic void fhanew_uninit(void *foo); 442160Scsgrrpcproc_t fhanew_get_procnum(rpcproc_t procnum); 452061Sjkhint fhanew_realign(struct mbuf **mb, int malloc_flags); 462061Sjkhint fhanew_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos); 472626Scsgrint fhanew_is_read(rpcproc_t procnum); 482626Scsgrint fhanew_is_write(rpcproc_t procnum); 492626Scsgrint fhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3, 502626Scsgr struct fha_info *info); 512061Sjkhint fhanew_no_offset(rpcproc_t procnum); 522061Sjkhvoid fhanew_set_locktype(rpcproc_t procnum, struct fha_info *info); 532061Sjkhstatic int fhenew_stats_sysctl(SYSCTL_HANDLER_ARGS); 542061Sjkh 552061Sjkhstatic struct fha_params fhanew_softc; 562061Sjkh 572061SjkhSYSCTL_DECL(_vfs_nfsd); 582061Sjkh 592061Sjkhextern int newnfs_nfsv3_procid[]; 602061Sjkhextern SVCPOOL *nfsrvd_pool; 612061Sjkh 622061SjkhSYSINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_init, NULL); 632061SjkhSYSUNINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_uninit, NULL); 642061Sjkh 652061Sjkhstatic void 662061Sjkhfhanew_init(void *foo) 672061Sjkh{ 682061Sjkh struct fha_params *softc; 692834Swollman 702834Swollman softc = &fhanew_softc; 712834Swollman 722834Swollman bzero(softc, sizeof(*softc)); 732834Swollman 742834Swollman /* 751594Srgrimes * Setup the callbacks for this FHA personality. 762061Sjkh */ 772061Sjkh softc->callbacks.get_procnum = fhanew_get_procnum; 782061Sjkh softc->callbacks.realign = fhanew_realign; 792061Sjkh softc->callbacks.get_fh = fhanew_get_fh; 802061Sjkh softc->callbacks.is_read = fhanew_is_read; 812061Sjkh softc->callbacks.is_write = fhanew_is_write; 822061Sjkh softc->callbacks.get_offset = fhanew_get_offset; 832061Sjkh softc->callbacks.no_offset = fhanew_no_offset; 842061Sjkh softc->callbacks.set_locktype = fhanew_set_locktype; 852061Sjkh softc->callbacks.fhe_stats_sysctl = fhenew_stats_sysctl; 862061Sjkh 872061Sjkh snprintf(softc->server_name, sizeof(softc->server_name), 882061Sjkh FHANEW_SERVER_NAME); 892061Sjkh 902061Sjkh softc->pool = &nfsrvd_pool; 912061Sjkh 922061Sjkh /* 932061Sjkh * Initialize the sysctl context list for the fha module. 942061Sjkh */ 952061Sjkh sysctl_ctx_init(&softc->sysctl_ctx); 962061Sjkh softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 972468Spaul SYSCTL_STATIC_CHILDREN(_vfs_nfsd), OID_AUTO, "fha", CTLFLAG_RD, 982061Sjkh 0, "fha node"); 992061Sjkh if (softc->sysctl_tree == NULL) { 1002061Sjkh printf("%s: unable to allocate sysctl tree\n", __func__); 1012061Sjkh return; 1022061Sjkh } 1032061Sjkh 1042061Sjkh fha_init(softc); 1052302Spaul} 1062061Sjkh 1072061Sjkhstatic void 1082061Sjkhfhanew_uninit(void *foo) 1092061Sjkh{ 1102302Spaul struct fha_params *softc; 1112061Sjkh 1122302Spaul softc = &fhanew_softc; 1132302Spaul 1142302Spaul fha_uninit(softc); 1152302Spaul} 1162302Spaul 1172302Spaulrpcproc_t 1182302Spaulfhanew_get_procnum(rpcproc_t procnum) 1192302Spaul{ 1202302Spaul if (procnum > NFSV2PROC_STATFS) 1212302Spaul return (-1); 1222302Spaul 1232302Spaul return (newnfs_nfsv3_procid[procnum]); 1242302Spaul} 1252302Spaul 1262061Sjkhint 1272061Sjkhfhanew_realign(struct mbuf **mb, int malloc_flags) 1282061Sjkh{ 1292061Sjkh return (newnfs_realign(mb, malloc_flags)); 1302061Sjkh} 1312061Sjkh 1322061Sjkhint 1332061Sjkhfhanew_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos) 1342061Sjkh{ 1352061Sjkh struct nfsrv_descript lnd, *nd; 1362061Sjkh uint32_t *tl; 1372061Sjkh uint8_t *buf; 1382061Sjkh uint64_t t; 1392061Sjkh int error, len, i; 1402061Sjkh 1412061Sjkh error = 0; 1422061Sjkh len = 0; 1432061Sjkh nd = &lnd; 1442061Sjkh 1452061Sjkh nd->nd_md = *md; 1462061Sjkh nd->nd_dpos = *dpos; 1472061Sjkh 1482061Sjkh if (v3) { 1492061Sjkh NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED); 1502061Sjkh if ((len = fxdr_unsigned(int, *tl)) <= 0 || len > NFSX_FHMAX) { 1512061Sjkh error = EBADRPC; 1522061Sjkh goto nfsmout; 1532061Sjkh } 1542061Sjkh } else { 1552061Sjkh len = NFSX_V2FH; 1562061Sjkh } 1572061Sjkh 1582061Sjkh t = 0; 1592061Sjkh if (len != 0) { 1602061Sjkh NFSM_DISSECT_NONBLOCK(buf, uint8_t *, len); 1612061Sjkh for (i = 0; i < len; i++) 1622061Sjkh t ^= ((uint64_t)buf[i] << (i & 7) * 8); 1632061Sjkh } 1642061Sjkh *fh = t; 1652061Sjkh 1662061Sjkhnfsmout: 1672061Sjkh *md = nd->nd_md; 1682061Sjkh *dpos = nd->nd_dpos; 1692061Sjkh 1702685Srgrimes return (error); 1712685Srgrimes} 1722626Scsgr 1732061Sjkhint 1742061Sjkhfhanew_is_read(rpcproc_t procnum) 1752061Sjkh{ 1762061Sjkh if (procnum == NFSPROC_READ) 1772061Sjkh return (1); 1782061Sjkh else 1792626Scsgr return (0); 1802626Scsgr} 1812626Scsgr 1822626Scsgrint 1832061Sjkhfhanew_is_write(rpcproc_t procnum) 1842061Sjkh{ 1852061Sjkh if (procnum == NFSPROC_WRITE) 1862061Sjkh return (1); 1872061Sjkh else 1882061Sjkh return (0); 1892061Sjkh} 1902061Sjkh 1912061Sjkhint 1922061Sjkhfhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3, 1932468Spaul struct fha_info *info) 1942061Sjkh{ 1952273Spaul struct nfsrv_descript lnd, *nd; 1962061Sjkh uint32_t *tl; 1972160Scsgr int error; 1982160Scsgr 1992160Scsgr error = 0; 2002160Scsgr 2012279Spaul nd = &lnd; 2022061Sjkh nd->nd_md = *md; 2032061Sjkh nd->nd_dpos = *dpos; 2042279Spaul 2052468Spaul if (v3) { 2062468Spaul NFSM_DISSECT_NONBLOCK(tl, uint32_t *, 2 * NFSX_UNSIGNED); 2072626Scsgr info->offset = fxdr_hyper(tl); 2082061Sjkh } else { 2092061Sjkh NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED); 2102061Sjkh info->offset = fxdr_unsigned(uint32_t, *tl); 2112061Sjkh } 2122061Sjkh 2132061Sjkhnfsmout: 2142061Sjkh *md = nd->nd_md; 2152061Sjkh *dpos = nd->nd_dpos; 2162061Sjkh 2172626Scsgr return (error); 2182626Scsgr} 2192626Scsgr 2202626Scsgrint 2212626Scsgrfhanew_no_offset(rpcproc_t procnum) 2222626Scsgr{ 2232626Scsgr if (procnum == NFSPROC_FSSTAT || 2242626Scsgr procnum == NFSPROC_FSINFO || 2252626Scsgr procnum == NFSPROC_PATHCONF || 2262626Scsgr procnum == NFSPROC_NOOP || 2272626Scsgr procnum == NFSPROC_NULL) 2282061Sjkh return (1); 2292061Sjkh else 2302061Sjkh return (0); 2312061Sjkh} 2322061Sjkh 2332061Sjkhvoid 2342273Spaulfhanew_set_locktype(rpcproc_t procnum, struct fha_info *info) 2352061Sjkh{ 2362061Sjkh switch (procnum) { 2372061Sjkh case NFSPROC_NULL: 2382061Sjkh case NFSPROC_GETATTR: 2391594Srgrimes case NFSPROC_LOOKUP: 240 case NFSPROC_ACCESS: 241 case NFSPROC_READLINK: 242 case NFSPROC_READ: 243 case NFSPROC_READDIR: 244 case NFSPROC_READDIRPLUS: 245 case NFSPROC_WRITE: 246 info->locktype = LK_SHARED; 247 break; 248 case NFSPROC_SETATTR: 249 case NFSPROC_CREATE: 250 case NFSPROC_MKDIR: 251 case NFSPROC_SYMLINK: 252 case NFSPROC_MKNOD: 253 case NFSPROC_REMOVE: 254 case NFSPROC_RMDIR: 255 case NFSPROC_RENAME: 256 case NFSPROC_LINK: 257 case NFSPROC_FSSTAT: 258 case NFSPROC_FSINFO: 259 case NFSPROC_PATHCONF: 260 case NFSPROC_COMMIT: 261 case NFSPROC_NOOP: 262 info->locktype = LK_EXCLUSIVE; 263 break; 264 } 265} 266 267static int 268fhenew_stats_sysctl(SYSCTL_HANDLER_ARGS) 269{ 270 return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhanew_softc)); 271} 272 273 274SVCTHREAD * 275fhanew_assign(SVCTHREAD *this_thread, struct svc_req *req) 276{ 277 return (fha_assign(this_thread, req, &fhanew_softc)); 278} 279