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> 43251641Sken#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); 52261061Smavint fhaold_get_fh(uint64_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 138261061Smavfhaold_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos) 139249592Sken{ 140261061Smav u_int32_t *tl; 141261061Smav uint8_t *buf; 142261061Smav uint64_t t; 143261061Smav int fhlen, i; 144261061Smav 145261061Smav if (v3) { 146261061Smav tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); 147261061Smav if (tl == NULL) 148261061Smav return EBADRPC; 149261061Smav fhlen = fxdr_unsigned(int, *tl); 150261061Smav if (fhlen != 0 && fhlen != NFSX_V3FH) 151261061Smav return EBADRPC; 152261061Smav } else { 153261061Smav fhlen = NFSX_V2FH; 154261061Smav } 155261061Smav t = 0; 156261061Smav if (fhlen != 0) { 157261061Smav buf = nfsm_dissect_xx_nonblock(fhlen, md, dpos); 158261061Smav if (buf == NULL) 159261061Smav return EBADRPC; 160261061Smav for (i = 0; i < fhlen; i++) 161261061Smav t ^= ((uint64_t)buf[i] << (i & 7) * 8); 162261061Smav } 163261061Smav *fh = t; 164261061Smav return 0; 165249592Sken} 166249592Sken 167249592Skenint 168249592Skenfhaold_is_read(rpcproc_t procnum) 169249592Sken{ 170249592Sken if (procnum == NFSPROC_READ) 171249592Sken return (1); 172249592Sken else 173249592Sken return (0); 174249592Sken} 175249592Sken 176249592Skenint 177249592Skenfhaold_is_write(rpcproc_t procnum) 178249592Sken{ 179249592Sken if (procnum == NFSPROC_WRITE) 180249592Sken return (1); 181249592Sken else 182249592Sken return (0); 183249592Sken} 184249592Sken 185249592Skenint 186249592Skenfhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3, 187249592Sken struct fha_info *info) 188249592Sken{ 189249592Sken uint32_t *tl; 190249592Sken 191249592Sken if (v3) { 192249592Sken tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos); 193249592Sken if (tl == NULL) 194249592Sken goto out; 195249592Sken info->offset = fxdr_hyper(tl); 196249592Sken } else { 197249592Sken tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); 198249592Sken if (tl == NULL) 199249592Sken goto out; 200249592Sken info->offset = fxdr_unsigned(uint32_t, *tl); 201249592Sken } 202249592Sken 203249592Sken return (0); 204249592Skenout: 205249592Sken return (-1); 206249592Sken} 207249592Sken 208249592Skenint 209249592Skenfhaold_no_offset(rpcproc_t procnum) 210249592Sken{ 211249592Sken if (procnum == NFSPROC_FSSTAT || 212249592Sken procnum == NFSPROC_FSINFO || 213249592Sken procnum == NFSPROC_PATHCONF || 214249592Sken procnum == NFSPROC_NOOP || 215249592Sken procnum == NFSPROC_NULL) 216249592Sken return (1); 217249592Sken else 218249592Sken return (0); 219249592Sken} 220249592Sken 221249592Skenvoid 222249592Skenfhaold_set_locktype(rpcproc_t procnum, struct fha_info *info) 223249592Sken{ 224249592Sken switch (procnum) { 225249592Sken case NFSPROC_NULL: 226249592Sken case NFSPROC_GETATTR: 227249592Sken case NFSPROC_LOOKUP: 228249592Sken case NFSPROC_ACCESS: 229249592Sken case NFSPROC_READLINK: 230249592Sken case NFSPROC_READ: 231249592Sken case NFSPROC_READDIR: 232249592Sken case NFSPROC_READDIRPLUS: 233249592Sken case NFSPROC_WRITE: 234249592Sken info->locktype = LK_SHARED; 235249592Sken break; 236249592Sken case NFSPROC_SETATTR: 237249592Sken case NFSPROC_CREATE: 238249592Sken case NFSPROC_MKDIR: 239249592Sken case NFSPROC_SYMLINK: 240249592Sken case NFSPROC_MKNOD: 241249592Sken case NFSPROC_REMOVE: 242249592Sken case NFSPROC_RMDIR: 243249592Sken case NFSPROC_RENAME: 244249592Sken case NFSPROC_LINK: 245249592Sken case NFSPROC_FSSTAT: 246249592Sken case NFSPROC_FSINFO: 247249592Sken case NFSPROC_PATHCONF: 248249592Sken case NFSPROC_COMMIT: 249249592Sken case NFSPROC_NOOP: 250249592Sken info->locktype = LK_EXCLUSIVE; 251249592Sken break; 252249592Sken } 253249592Sken} 254249592Sken 255249592Skenstatic int 256249592Skenfheold_stats_sysctl(SYSCTL_HANDLER_ARGS) 257249592Sken{ 258249592Sken return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhaold_softc)); 259249592Sken} 260249592Sken 261249592SkenSVCTHREAD * 262249592Skenfhaold_assign(SVCTHREAD *this_thread, struct svc_req *req) 263249592Sken{ 264249592Sken return (fha_assign(this_thread, req, &fhaold_softc)); 265249592Sken} 266