nfs_fha_new.c revision 249596
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: head/sys/fs/nfsserver/nfs_fha_new.c 249596 2013-04-17 22:42:43Z ken $"); 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); 44249592Skenint fhanew_get_fh(fhandle_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, 96249592Sken 0, "fha node"); 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 131249592Skenfhanew_get_fh(fhandle_t *fh, int v3, struct mbuf **md, caddr_t *dpos) 132249592Sken{ 133249592Sken struct nfsrv_descript lnd, *nd; 134249592Sken uint32_t *tl; 135249592Sken int error, len; 136249592Sken 137249592Sken error = 0; 138249592Sken len = 0; 139249592Sken nd = &lnd; 140249592Sken 141249592Sken nd->nd_md = *md; 142249592Sken nd->nd_dpos = *dpos; 143249592Sken 144249592Sken if (v3) { 145249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED); 146249592Sken if ((len = fxdr_unsigned(int, *tl)) <= 0 || len > NFSX_FHMAX) { 147249592Sken error = EBADRPC; 148249592Sken goto nfsmout; 149249592Sken } 150249592Sken } else { 151249592Sken len = NFSX_V2FH; 152249592Sken } 153249592Sken 154249592Sken if (len != 0) { 155249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, len); 156249592Sken bcopy(tl, fh, len); 157249592Sken } else 158249592Sken bzero(fh, sizeof(*fh)); 159249592Sken 160249592Skennfsmout: 161249592Sken *md = nd->nd_md; 162249592Sken *dpos = nd->nd_dpos; 163249592Sken 164249592Sken return (error); 165249592Sken} 166249592Sken 167249592Skenint 168249592Skenfhanew_is_read(rpcproc_t procnum) 169249592Sken{ 170249592Sken if (procnum == NFSPROC_READ) 171249592Sken return (1); 172249592Sken else 173249592Sken return (0); 174249592Sken} 175249592Sken 176249592Skenint 177249592Skenfhanew_is_write(rpcproc_t procnum) 178249592Sken{ 179249592Sken if (procnum == NFSPROC_WRITE) 180249592Sken return (1); 181249592Sken else 182249592Sken return (0); 183249592Sken} 184249592Sken 185249592Skenint 186249592Skenfhanew_get_offset(struct mbuf **md, caddr_t *dpos, int v3, 187249592Sken struct fha_info *info) 188249592Sken{ 189249592Sken struct nfsrv_descript lnd, *nd; 190249592Sken uint32_t *tl; 191249592Sken int error; 192249592Sken 193249592Sken error = 0; 194249592Sken 195249592Sken nd = &lnd; 196249592Sken nd->nd_md = *md; 197249592Sken nd->nd_dpos = *dpos; 198249592Sken 199249592Sken if (v3) { 200249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, 2 * NFSX_UNSIGNED); 201249592Sken info->offset = fxdr_hyper(tl); 202249592Sken } else { 203249592Sken NFSM_DISSECT_NONBLOCK(tl, uint32_t *, NFSX_UNSIGNED); 204249592Sken info->offset = fxdr_unsigned(uint32_t, *tl); 205249592Sken } 206249592Sken 207249592Skennfsmout: 208249592Sken *md = nd->nd_md; 209249592Sken *dpos = nd->nd_dpos; 210249592Sken 211249592Sken return (error); 212249592Sken} 213249592Sken 214249592Skenint 215249592Skenfhanew_no_offset(rpcproc_t procnum) 216249592Sken{ 217249592Sken if (procnum == NFSPROC_FSSTAT || 218249592Sken procnum == NFSPROC_FSINFO || 219249592Sken procnum == NFSPROC_PATHCONF || 220249592Sken procnum == NFSPROC_NOOP || 221249592Sken procnum == NFSPROC_NULL) 222249592Sken return (1); 223249592Sken else 224249592Sken return (0); 225249592Sken} 226249592Sken 227249592Skenvoid 228249592Skenfhanew_set_locktype(rpcproc_t procnum, struct fha_info *info) 229249592Sken{ 230249592Sken switch (procnum) { 231249592Sken case NFSPROC_NULL: 232249592Sken case NFSPROC_GETATTR: 233249592Sken case NFSPROC_LOOKUP: 234249592Sken case NFSPROC_ACCESS: 235249592Sken case NFSPROC_READLINK: 236249592Sken case NFSPROC_READ: 237249592Sken case NFSPROC_READDIR: 238249592Sken case NFSPROC_READDIRPLUS: 239249592Sken case NFSPROC_WRITE: 240249592Sken info->locktype = LK_SHARED; 241249592Sken break; 242249592Sken case NFSPROC_SETATTR: 243249592Sken case NFSPROC_CREATE: 244249592Sken case NFSPROC_MKDIR: 245249592Sken case NFSPROC_SYMLINK: 246249592Sken case NFSPROC_MKNOD: 247249592Sken case NFSPROC_REMOVE: 248249592Sken case NFSPROC_RMDIR: 249249592Sken case NFSPROC_RENAME: 250249592Sken case NFSPROC_LINK: 251249592Sken case NFSPROC_FSSTAT: 252249592Sken case NFSPROC_FSINFO: 253249592Sken case NFSPROC_PATHCONF: 254249592Sken case NFSPROC_COMMIT: 255249592Sken case NFSPROC_NOOP: 256249592Sken info->locktype = LK_EXCLUSIVE; 257249592Sken break; 258249592Sken } 259249592Sken} 260249592Sken 261249592Skenstatic int 262249592Skenfhenew_stats_sysctl(SYSCTL_HANDLER_ARGS) 263249592Sken{ 264249592Sken return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhanew_softc)); 265249592Sken} 266249592Sken 267249592Sken 268249592SkenSVCTHREAD * 269249592Skenfhanew_assign(SVCTHREAD *this_thread, struct svc_req *req) 270249592Sken{ 271249592Sken return (fha_assign(this_thread, req, &fhanew_softc)); 272249592Sken} 273