/*************************************************************************** * * Copyright (C) 2001 International Business Machines * All rights reserved. * * This file is part of the GPFS mmfslinux kernel module. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *************************************************************************** */ /* @(#)68 1.66.1.13 src/avs/fs/mmfs/ts/kernext/gpl-linux/gplInit.c, mmfs, avs_rgpfs24, rgpfs24s012a 4/6/07 16:11:44 */ /* * Initialize the linux module * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern char *prog_path; struct gpfs_operations gpfs_ops; /* This string must match (in the strcmp sense) PRODUCT_VERSION defined in prodname.h. It is used to make sure that mmfslinux module matches the rest of the code. */ #define PRODUCT_VERSION "3.1.0.12 " #ifdef MODULE #if (LINUX_KERNEL_VERSION >= 2040900) MODULE_LICENSE("GPL"); MODULE_DESCRIPTION ("GPFS portability layer"); MODULE_AUTHOR ("IBM "); #endif /* The module pointer for the mmfs module. Exported * to the mmfs portability layer module. Its reference * counts are updated via cxiIncModuleCounter(). */ static struct module *ibmModule = 0; static struct module *ibmModuleLoaded = 0; void cxiExportModuleStruct(void *modAddr) { ibmModule = (struct module *)modAddr; } void cxiIncModuleCounter(int up) { TRACE2(TRACE_VNODE, 1, TRCID_CXIINC_COUNTER, "cxiIncModuleCounter: ibmModule 0x%X up %d\n", ibmModule, up); if (ibmModule) { if (up) { MODULE_INCREMENT(ibmModule); ibmModuleLoaded = ibmModule; } else if (ibmModuleLoaded) MODULE_DECREMENT(ibmModule); } } #else /* ! MODULE */ static void *ibmModule = 0; void cxiExportModuleStruct(void *modAddr) {}; void cxiIncModuleCounter(int up) {}; #endif /* MODULE */ extern char bin_path[CXI_MAXPATHLEN+1]; extern char mmfs_path[CXI_MAXPATHLEN+1]; extern int mmfsd_module_active; /* Dummy operations for initializing gpfs_operations table. Using this dummy operation instead of storing a NULL function pointer avoids having to check for NULL before each call. */ void gpfs_void_op() { } int gpfs_enosys_op() { return ENOSYS; } int gpfs_zero_op() { return 0; } void * gpfs_nullptr_op() { return NULL; } typedef void (*VoidFnP)(); typedef int (*IntFnP)(); typedef void * (*PtrFnP)(); /* initialize gpfs_operations table */ void reset_gpfs_operations() { gpfs_ops.mmfs = 0; * (IntFnP *) & gpfs_ops.gpfsMount = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsStatfs = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsSyncfs = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFsync = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsSyncNFS = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsMkdir = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsLink = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsOpen = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsInodeRead = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsInodeDelete = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsInodeFindActor = (IntFnP)gpfs_zero_op; * (IntFnP *) & gpfs_ops.gpfsGetSnapIdPair = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsRemove = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsRename = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsRmdir = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsSetattr = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsSymlink = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFsyncRange = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsClose = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsUnmap = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFattr = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFsAttr = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFclear = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFtrunc = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsRead = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsWrite = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetattr = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsAccess = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsReaddir = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsReadlink = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsCreate = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsMknod = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsRele = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsLookup = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsFcntl = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsUncache = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsUnmount = (IntFnP)gpfs_enosys_op; * (VoidFnP*) & gpfs_ops.gpfsFinishUnmount = (VoidFnP)gpfs_void_op; #ifdef NFS4_CLUSTER * (IntFnP*) & gpfs_ops.gpfsFsLocations = (IntFnP)gpfs_enosys_op; #endif * (IntFnP *) & gpfs_ops.gpfsFcntlReset = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetAcl = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsPutAcl = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetNFS = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsReleaseNFS = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsReady = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsMmap = (IntFnP)gpfs_enosys_op; #ifdef SMB_LOCKS * (IntFnP *) & gpfs_ops.SMBOpenLockControl = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.SMBGetOplockState = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.SMBGetOplockStateV = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsSetSMBOplock = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsReserveShare = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsReserveDelegation = (IntFnP)gpfs_enosys_op; #endif * (IntFnP *) & gpfs_ops.gpfsDaemonToDie = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsCleanup = (IntFnP)gpfs_enosys_op; #ifdef UIDREMAP * (IntFnP *) & gpfs_ops.UIDremapOn = (IntFnP)gpfs_enosys_op; #endif * (VoidFnP*) & gpfs_ops.gpfsSwapdEnqueue = (VoidFnP)gpfs_enosys_op; * (VoidFnP*) & gpfs_ops.gpfsQueueBufs = (VoidFnP)gpfs_enosys_op; * (VoidFnP*) & gpfs_ops.gpfsMmapFlushLock = (VoidFnP)gpfs_enosys_op; * (VoidFnP*) & gpfs_ops.gpfsMmapFlushUnlock = (VoidFnP)gpfs_enosys_op; #ifdef DMAPI * (VoidFnP*) & gpfs_ops.gpfsDmUnmountEvent = (VoidFnP)gpfs_enosys_op; #endif * (VoidFnP*) & gpfs_ops.gpfsNFSIget = (VoidFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsOpenNFS = (IntFnP)gpfs_enosys_op; * (VoidFnP*) & gpfs_ops.gpfsGrace = (VoidFnP)gpfs_enosys_op; #ifdef P_NFS4 * (IntFnP *) & gpfs_ops.gpfsGetDeviceList = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetLayout = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetOpenState = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsLayoutRetrun = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetDeviceInfo = (IntFnP)gpfs_enosys_op; * (IntFnP *) & gpfs_ops.gpfsGetMyDevID = (IntFnP)gpfs_enosys_op; * (VoidFnP *) & gpfs_ops.gpfsGetVerifier = (IntFnP)gpfs_enosys_op; #endif #ifdef GPFS_QUOTACTL * (IntFnP *) & gpfs_ops.gpfsQuotactl = (IntFnP)gpfs_enosys_op; #endif }; void gpfs_clean() { kill_mmfsd(); if (gpfs_ops.mmfs) { gpfs_ops.mmfs(CFG_TERM); } gpfs_unreg_fs(); #if LINUX_KERNEL_VERSION < 2050000 /* GPFS on Linux 2.5 uses an anonymous mount */ gpfs_block_clean(); #endif } int gpfs_init() { if (strlen(prog_path) > CXI_MAXPATHLEN) { TRACE2(TRACE_SHARED, 0, TRCID_GPFSINIT_000, "gpfs_init: prog_path %s length %d too long\n", prog_path, strlen(prog_path)); return -1; } #if LINUX_KERNEL_VERSION < 2050000 /* GPFS on Linux 2.5 uses an anonymous mount */ if (gpfs_block_init()) return -1; if (gpfs_reg_fs()) { gpfs_block_clean(); return -1; } #else if (gpfs_reg_fs()) return -1; #endif if (gpfs_ops.mmfs) { if (gpfs_ops.mmfs(CFG_INIT)) { gpfs_clean(); return -1; } } else return -1; strcpy(bin_path, prog_path); return 0; } int cxiCheckProductVersion(const char* mmfsProductVersion) { if (cxiStrcmp(mmfsProductVersion, PRODUCT_VERSION) != 0) { TRACE2(TRACE_VNODE, 0, TRCID_PRODVER_MISMATCH, "mmfslinux product version %s does not match mmfs version %s", PRODUCT_VERSION, mmfsProductVersion); /* Since getting a trace of an early startup failure is awkward, we should make the issue more obvious. */ printk("GPFS mmfslinux product version %s does not match mmfs version %s", PRODUCT_VERSION, mmfsProductVersion); return EINVAL; } return 0; } int cxiCheckSiteMcrVersion(const char* siteMcrVersion) { if (cxiStrcmp(siteMcrVersion, SITEMCRREV) != 0) { TRACE2(TRACE_VNODE, 0, TRCID_STEMCRVER_MISMATCH, "mmfslinux was built with site.mcr rev %s which does not match " "the site.mcr version %s used to build mmfs", SITEMCRREV, siteMcrVersion); /* Since getting a trace of an early startup failure is awkward, we should make the issue more obvious. */ printk("mmfslinux was built with site.mcr rev %s which does not match " "the site.mcr version %s used to build mmfs", SITEMCRREV, siteMcrVersion); return EINVAL; } return 0; } /* Module initialization */ MY_INIT_FUNCTION() { int i; #ifdef KSTACK_CHECK shInit(); #endif #ifdef MALLOC_DEBUG MallocDebugStart(); #endif for (i=0 ; i