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: stable/11/sys/fs/nfsserver/nfs_fha_new.c 322137 2017-08-07 07:02:51Z mav $"); 29249592Sken 30249592Sken#include <fs/nfs/nfsport.h> 31249592Sken 32249592Sken#include <rpc/rpc.h> 33249596Sken#include <nfs/nfs_fha.h> 34249592Sken#include <fs/nfs/xdr_subs.h> 35249592Sken#include <fs/nfs/nfs.h> 36249592Sken#include <fs/nfs/nfsproto.h> 37249592Sken#include <fs/nfs/nfsm_subs.h> 38249592Sken#include <fs/nfsserver/nfs_fha_new.h> 39249592Sken 40249592Skenstatic void fhanew_init(void *foo); 41249592Skenstatic void fhanew_uninit(void *foo); 42249592Skenrpcproc_t fhanew_get_procnum(rpcproc_t procnum); 43249592Skenint fhanew_realign(struct mbuf **mb, int malloc_flags); 44259765Smavint fhanew_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos); 45249592Skenint fhanew_is_read(rpcproc_t procnum); 46249592Skenint fhanew_is_write(rpcproc_t procnum); 47249592Skenint fhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3, 48249592Sken struct fha_info *info); 49249592Skenint fhanew_no_offset(rpcproc_t procnum); 50249592Skenvoid fhanew_set_locktype(rpcproc_t procnum, struct fha_info *info); 51249592Skenstatic int fhenew_stats_sysctl(SYSCTL_HANDLER_ARGS); 52249592Sken 53249592Skenstatic struct fha_params fhanew_softc; 54249592Sken 55249592SkenSYSCTL_DECL(_vfs_nfsd); 56249592Sken 57249592Skenextern int newnfs_nfsv3_procid[]; 58249592Skenextern SVCPOOL *nfsrvd_pool; 59249592Sken 60249592SkenSYSINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_init, NULL); 61249592SkenSYSUNINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_uninit, NULL); 62249592Sken 63249592Skenstatic void 64249592Skenfhanew_init(void *foo) 65249592Sken{ 66249592Sken struct fha_params *softc; 67249592Sken 68249592Sken softc = &fhanew_softc; 69249592Sken 70249592Sken bzero(softc, sizeof(*softc)); 71249592Sken 72249592Sken /* 73249592Sken * Setup the callbacks for this FHA personality. 74249592Sken */ 75249592Sken softc->callbacks.get_procnum = fhanew_get_procnum; 76249592Sken softc->callbacks.realign = fhanew_realign; 77249592Sken softc->callbacks.get_fh = fhanew_get_fh; 78249592Sken softc->callbacks.is_read = fhanew_is_read; 79249592Sken softc->callbacks.is_write = fhanew_is_write; 80249592Sken softc->callbacks.get_offset = fhanew_get_offset; 81249592Sken softc->callbacks.no_offset = fhanew_no_offset; 82249592Sken softc->callbacks.set_locktype = fhanew_set_locktype; 83249592Sken softc->callbacks.fhe_stats_sysctl = fhenew_stats_sysctl; 84249592Sken 85249592Sken snprintf(softc->server_name, sizeof(softc->server_name), 86249592Sken FHANEW_SERVER_NAME); 87249592Sken 88249592Sken softc->pool = &nfsrvd_pool; 89249592Sken 90249592Sken /* 91249592Sken * Initialize the sysctl context list for the fha module. 92249592Sken */ 93249592Sken sysctl_ctx_init(&softc->sysctl_ctx); 94249592Sken softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 95249592Sken SYSCTL_STATIC_CHILDREN(_vfs_nfsd), OID_AUTO, "fha", CTLFLAG_RD, 96322137Smav 0, "NFS File Handle Affinity (FHA)"); 97249592Sken if (softc->sysctl_tree == NULL) { 98249592Sken printf("%s: unable to allocate sysctl tree\n", __func__); 99249592Sken return; 100249592Sken } 101249592Sken 102249592Sken fha_init(softc); 103249592Sken} 104249592Sken 105249592Skenstatic void 106249592Skenfhanew_uninit(void *foo) 107249592Sken{ 108249592Sken struct fha_params *softc; 109249592Sken 110249592Sken softc = &fhanew_softc; 111249592Sken 112249592Sken fha_uninit(softc); 113249592Sken} 114249592Sken 115249592Skenrpcproc_t 116249592Skenfhanew_get_procnum(rpcproc_t procnum) 117249592Sken{ 118249592Sken if (procnum > NFSV2PROC_STATFS) 119249592Sken return (-1); 120249592Sken 121249592Sken return (newnfs_nfsv3_procid[procnum]); 122249592Sken} 123249592Sken 124249592Skenint 125249592Skenfhanew_realign(struct mbuf **mb, int malloc_flags) 126249592Sken{ 127249592Sken return (newnfs_realign(mb, malloc_flags)); 128249592Sken} 129249592Sken 130249592Skenint 131259765Smavfhanew_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos) 132249592Sken{ 133249592Sken struct nfsrv_descript lnd, *nd; 134249592Sken uint32_t *tl; 135259765Smav uint8_t *buf; 136259765Smav uint64_t t; 137259765Smav int error, len, i; 138249592Sken 139249592Sken error = 0; 140249592Sken len = 0; 141249592Sken nd = &lnd; 142249592Sken 143249592Sken nd->nd_md = *md; 144249592Sken nd->nd_dpos = *dpos; 145249592Sken 146249592Sken if (v3) { 147249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED); 148249592Sken if ((len = fxdr_unsigned(int, *tl)) <= 0 || len > NFSX_FHMAX) { 149249592Sken error = EBADRPC; 150249592Sken goto nfsmout; 151249592Sken } 152249592Sken } else { 153249592Sken len = NFSX_V2FH; 154249592Sken } 155249592Sken 156259765Smav t = 0; 157249592Sken if (len != 0) { 158259765Smav NFSM_DISSECT_NONBLOCK(buf, uint8_t *, len); 159259765Smav for (i = 0; i < len; i++) 160259765Smav t ^= ((uint64_t)buf[i] << (i & 7) * 8); 161259765Smav } 162259765Smav *fh = t; 163249592Sken 164249592Skennfsmout: 165249592Sken *md = nd->nd_md; 166249592Sken *dpos = nd->nd_dpos; 167249592Sken 168249592Sken return (error); 169249592Sken} 170249592Sken 171249592Skenint 172249592Skenfhanew_is_read(rpcproc_t procnum) 173249592Sken{ 174249592Sken if (procnum == NFSPROC_READ) 175249592Sken return (1); 176249592Sken else 177249592Sken return (0); 178249592Sken} 179249592Sken 180249592Skenint 181249592Skenfhanew_is_write(rpcproc_t procnum) 182249592Sken{ 183249592Sken if (procnum == NFSPROC_WRITE) 184249592Sken return (1); 185249592Sken else 186249592Sken return (0); 187249592Sken} 188249592Sken 189249592Skenint 190249592Skenfhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3, 191249592Sken struct fha_info *info) 192249592Sken{ 193249592Sken struct nfsrv_descript lnd, *nd; 194249592Sken uint32_t *tl; 195249592Sken int error; 196249592Sken 197249592Sken error = 0; 198249592Sken 199249592Sken nd = &lnd; 200249592Sken nd->nd_md = *md; 201249592Sken nd->nd_dpos = *dpos; 202249592Sken 203249592Sken if (v3) { 204249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, 2 * NFSX_UNSIGNED); 205249592Sken info->offset = fxdr_hyper(tl); 206249592Sken } else { 207249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED); 208249592Sken info->offset = fxdr_unsigned(uint32_t, *tl); 209249592Sken } 210249592Sken 211249592Skennfsmout: 212249592Sken *md = nd->nd_md; 213249592Sken *dpos = nd->nd_dpos; 214249592Sken 215249592Sken return (error); 216249592Sken} 217249592Sken 218249592Skenint 219249592Skenfhanew_no_offset(rpcproc_t procnum) 220249592Sken{ 221249592Sken if (procnum == NFSPROC_FSSTAT || 222249592Sken procnum == NFSPROC_FSINFO || 223249592Sken procnum == NFSPROC_PATHCONF || 224249592Sken procnum == NFSPROC_NOOP || 225249592Sken procnum == NFSPROC_NULL) 226249592Sken return (1); 227249592Sken else 228249592Sken return (0); 229249592Sken} 230249592Sken 231249592Skenvoid 232249592Skenfhanew_set_locktype(rpcproc_t procnum, struct fha_info *info) 233249592Sken{ 234249592Sken switch (procnum) { 235249592Sken case NFSPROC_NULL: 236249592Sken case NFSPROC_GETATTR: 237249592Sken case NFSPROC_LOOKUP: 238249592Sken case NFSPROC_ACCESS: 239249592Sken case NFSPROC_READLINK: 240249592Sken case NFSPROC_READ: 241249592Sken case NFSPROC_READDIR: 242249592Sken case NFSPROC_READDIRPLUS: 243249592Sken case NFSPROC_WRITE: 244249592Sken info->locktype = LK_SHARED; 245249592Sken break; 246249592Sken case NFSPROC_SETATTR: 247249592Sken case NFSPROC_CREATE: 248249592Sken case NFSPROC_MKDIR: 249249592Sken case NFSPROC_SYMLINK: 250249592Sken case NFSPROC_MKNOD: 251249592Sken case NFSPROC_REMOVE: 252249592Sken case NFSPROC_RMDIR: 253249592Sken case NFSPROC_RENAME: 254249592Sken case NFSPROC_LINK: 255249592Sken case NFSPROC_FSSTAT: 256249592Sken case NFSPROC_FSINFO: 257249592Sken case NFSPROC_PATHCONF: 258249592Sken case NFSPROC_COMMIT: 259249592Sken case NFSPROC_NOOP: 260249592Sken info->locktype = LK_EXCLUSIVE; 261249592Sken break; 262249592Sken } 263249592Sken} 264249592Sken 265249592Skenstatic int 266249592Skenfhenew_stats_sysctl(SYSCTL_HANDLER_ARGS) 267249592Sken{ 268249592Sken return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhanew_softc)); 269249592Sken} 270249592Sken 271249592Sken 272249592SkenSVCTHREAD * 273249592Skenfhanew_assign(SVCTHREAD *this_thread, struct svc_req *req) 274249592Sken{ 275249592Sken return (fha_assign(this_thread, req, &fhanew_softc)); 276249592Sken} 277