/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* * osi_vfsops.c for HPUX */ #include #include "afs/param.h" #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ #include "afs/afs_stats.h" /* statistics stuff */ #include #if defined(AFS_HPUX1123_ENV) #include #endif /* AFS_HPUX1123_ENV */ #if defined(AFS_HPUX1123_ENV) /* defind DLKM tables so we can load dynamicly */ /* we still need an afs_unload to unload */ /* Note: There is to be a dependency on the * the name of the struct _wrapper, and the * name of the dynamicly loaded file * We will define -DAFS_WRAPPER=_wrapper * and -DAFS_CONF_DATA=_conf_data and pass into * this routine */ extern struct mod_operations mod_misc_ops; extern struct mod_conf_data AFS_CONF_DATA; static int afs_load(void *arg); /* static int afs_unload(void *arg); */ struct mod_type_data afs_mod_link = { "AFS kernel module", NULL }; struct modlink afs_modlink[] = { {&mod_misc_ops, &afs_mod_link}, { NULL, NULL } }; struct modwrapper AFS_WRAPPER = { MODREV, afs_load, NULL, /* should be afs_unload if we had one */ NULL, &AFS_CONF_DATA, afs_modlink }; #endif /* AFS_HPUX1123_ENV */ static char afs_mountpath[512]; struct vfs *afs_globalVFS = 0; struct vcache *afs_globalVp = 0; int afs_mount(struct vfs *afsp, char *path, smountargs_t * data) { AFS_GLOCK(); AFS_STATCNT(afs_mount); if (afs_globalVFS) { /* Don't allow remounts. */ AFS_GUNLOCK(); return (setuerror(EBUSY)); } afs_globalVFS = afsp; afsp->vfs_bsize = 8192; afsp->vfs_fsid[0] = AFS_VFSMAGIC; /* magic */ afsp->vfs_fsid[1] = AFS_VFSFSID; strcpy(afsp->vfs_name, "AFS"); afsp->vfs_name[3] = '\0'; strncpy(afs_mountpath, path, sizeof(afs_mountpath)); afs_mountpath[sizeof afs_mountpath - 1] = '\0'; #ifndef AFS_NONFSTRANS /* Set up the xlator in case it wasn't done elsewhere */ afs_xlatorinit_v2(); #endif AFS_GUNLOCK(); return 0; } int afs_unmount(struct vfs *afsp) { AFS_GLOCK(); AFS_STATCNT(afs_unmount); afs_globalVFS = 0; afs_shutdown(AFS_WARM); AFS_GUNLOCK(); return 0; } int afs_root(struct vfs *afsp, struct vnode **avpp, char *unused1) { int code = 0; struct vrequest treq; struct vcache *tvp = 0; AFS_GLOCK(); AFS_STATCNT(afs_root); if (afs_globalVp && (afs_globalVp->f.states & CStatd)) { tvp = afs_globalVp; } else { if (afs_globalVp) { afs_PutVCache(afs_globalVp); afs_globalVp = NULL; } if (!(code = afs_InitReq(&treq, p_cred(u.u_procp))) && !(code = afs_CheckInit())) { tvp = afs_GetVCache(&afs_rootFid, &treq); /* we really want this to stay around */ if (tvp) { afs_globalVp = tvp; } else code = EIO; } } if (tvp) { VN_HOLD(AFSTOV(tvp)); SET_V_FLAG(AFSTOV(tvp), VROOT); afs_globalVFS = afsp; *avpp = AFSTOV(tvp); } afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp, ICL_TYPE_INT32, code); AFS_GUNLOCK(); return code; } int afs_statfs(struct vfs *afsp, struct k_statvfs *abp) { AFS_GLOCK(); AFS_STATCNT(afs_statfs); abp->f_type = 0; abp->f_frsize = 1024; abp->f_bsize = afsp->vfs_bsize; /* Fake a high number below to satisfy programs that use the statfs * call to make sure that there's enough space in the device partition * before storing something there. */ abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = abp->f_ffree = abp->f_favail = AFS_VFS_FAKEFREE; abp->f_fsid = (AFS_VFSMAGIC << 16) | AFS_VFSFSID; AFS_GUNLOCK(); return 0; } int afs_sync(struct vfs *unused1, int unused2) { AFS_STATCNT(afs_sync); return 0; } int afs_vget(struct vfs *afsp, struct vnode **avcp, struct fid *fidp) { int code; struct vrequest treq; AFS_GLOCK(); AFS_STATCNT(afs_vget); *avcp = NULL; if ((code = afs_InitReq(&treq, p_cred(u.u_procp))) == 0) { code = afs_osi_vget((struct vcache **)avcp, fidp, &treq); } afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp, ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp); code = afs_CheckCode(code, &treq, 42); AFS_GUNLOCK(); return code; } int afs_getmount(struct vfs *vfsp, char *fsmntdir, struct mount_data *mdp, char *unused1) { int l; mdp->md_msite = 0; mdp->md_dev = 0; mdp->md_rdev = 0; return (copyoutstr (afs_mountpath, fsmntdir, strlen(afs_mountpath) + 1, &l)); } struct vfsops Afs_vfsops = { afs_mount, afs_unmount, afs_root, afs_statfs, afs_sync, afs_vget, afs_getmount, (vfs_freeze_t *) 0, /* vfs_freeze */ (vfs_thaw_t *) 0, /* vfs_thaw */ (vfs_quota_t *) 0, /* vfs_quota */ (vfs_mountroot_t *) 0, /* vfs_mountroot. Note: afs_mountroot_nullop in this * position panicked HP 11.00+ */ (vfs_size_t *) 0 /* vfs_size */ }; static int afs_Starting = 0; #pragma align 64 #if !defined(AFS_HPUX110_ENV) sema_t afs_global_sema = { NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, /* sa_type */ 0, 0, 0, 0, 0, 0, 0, NULL, /* sa_link */ NULL, NULL #ifdef SEMA_COUNTING , 0, 0, 0, NULL #endif }; #else b_sema_t afs_global_sema = { 0 }; #endif void osi_InitGlock() { ulong_t context; SPINLOCK_USAV(sched_lock, context); if (!afs_Starting) { afs_Starting = 1; SPINUNLOCK_USAV(sched_lock, context); #if defined(AFS_HPUX110_ENV) b_initsema(&afs_global_sema, 1, NFS_LOCK_ORDER2, "AFS GLOCK"); /* afsHash(64); *//* 64 buckets */ #else initsema(&afs_global_sema, 1, FILESYS_SEMA_PRI, FILESYS_SEMA_ORDER); afsHash(64); /* 64 buckets */ #endif } else { SPINUNLOCK_USAV(sched_lock, context); } if (!afs_Starting) { osi_Panic("osi_Init lost initialization race"); } } #if defined(AFS_HPUX1123_ENV) /* DLKM routine called when loaded */ static int afs_load(void *arg) { afsc_link(); return 0; } #endif /* AFS_HPUX1123_ENV */ /* * afsc_link - Initialize VFS */ int afs_vfs_slot = -1; afsc_link() { extern int Afs_syscall(), afs_xioctl(), Afs_xsetgroups(); /* For now nothing special is required during AFS initialization. */ AFS_STATCNT(afsc_link); osi_Init(); if ((afs_vfs_slot = add_vfs_type("afs", &Afs_vfsops)) < 0) return; sysent_assign_function(AFS_SYSCALL, 7, (void (*)())Afs_syscall, "Afs_syscall"); sysent_define_arg(AFS_SYSCALL, 0, longArg); sysent_define_arg(AFS_SYSCALL, 1, longArg); sysent_define_arg(AFS_SYSCALL, 2, longArg); sysent_define_arg(AFS_SYSCALL, 3, longArg); sysent_define_arg(AFS_SYSCALL, 4, longArg); sysent_define_arg(AFS_SYSCALL, 5, longArg); sysent_define_arg(AFS_SYSCALL, 6, longArg); sysent_returns_long(AFS_SYSCALL); sysent_delete(80); sysent_assign_function(80, 2, (void (*)())Afs_xsetgroups, "setgroups"); sysent_define_arg(80, 0, longArg); sysent_define_arg(80, 1, longArg); sysent_returns_long(80); return 0; }