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