154371Ssemenu/*- 254371Ssemenu * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org) 354371Ssemenu * All rights reserved. 454371Ssemenu * 554371Ssemenu * Redistribution and use in source and binary forms, with or without 654371Ssemenu * modification, are permitted provided that the following conditions 754371Ssemenu * are met: 854371Ssemenu * 1. Redistributions of source code must retain the above copyright 954371Ssemenu * notice, this list of conditions and the following disclaimer. 1054371Ssemenu * 2. Redistributions in binary form must reproduce the above copyright 1154371Ssemenu * notice, this list of conditions and the following disclaimer in the 1254371Ssemenu * documentation and/or other materials provided with the distribution. 1354371Ssemenu * 1454371Ssemenu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1554371Ssemenu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1654371Ssemenu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1754371Ssemenu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1854371Ssemenu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1954371Ssemenu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2054371Ssemenu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2154371Ssemenu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2254371Ssemenu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2354371Ssemenu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2454371Ssemenu * SUCH DAMAGE. 2554371Ssemenu * 2654371Ssemenu * $FreeBSD$ 2754371Ssemenu */ 2854371Ssemenu 2954371Ssemenu 3054371Ssemenu#include <sys/param.h> 3154371Ssemenu#include <sys/systm.h> 3254371Ssemenu#include <sys/namei.h> 3354371Ssemenu#include <sys/conf.h> 3454371Ssemenu#include <sys/proc.h> 3554371Ssemenu#include <sys/kernel.h> 3654371Ssemenu#include <sys/vnode.h> 3754371Ssemenu#include <sys/mount.h> 3860041Sphk#include <sys/bio.h> 3954371Ssemenu#include <sys/buf.h> 4054371Ssemenu#include <sys/fcntl.h> 4154371Ssemenu#include <sys/malloc.h> 4254371Ssemenu 43137040Sphk#include <geom/geom.h> 44137040Sphk#include <geom/geom_vfs.h> 45137040Sphk 4654371Ssemenu#include <vm/vm.h> 4754371Ssemenu#include <vm/vm_param.h> 4854371Ssemenu#include <vm/vm_page.h> 4954371Ssemenu#include <vm/vm_object.h> 5054371Ssemenu#include <vm/vm_extern.h> 5154371Ssemenu 5254371Ssemenu#include <fs/hpfs/hpfs.h> 5354371Ssemenu#include <fs/hpfs/hpfsmount.h> 5454371Ssemenu#include <fs/hpfs/hpfs_subr.h> 5554371Ssemenu 56151897SrwatsonMALLOC_DEFINE(M_HPFSMNT, "hpfs_mount", "HPFS mount structure"); 57151897SrwatsonMALLOC_DEFINE(M_HPFSNO, "hpfs_node", "HPFS node structure"); 5883384Sjhb 5986927Sjhbstruct sockaddr; 6086927Sjhb 6192727Salfredstatic int hpfs_mountfs(register struct vnode *, struct mount *, 62138487Sphk struct thread *); 6354371Ssemenu 64116271Sphkstatic vfs_fhtovp_t hpfs_fhtovp; 65116271Sphkstatic vfs_vget_t hpfs_vget; 66138487Sphkstatic vfs_cmount_t hpfs_cmount; 67138487Sphkstatic vfs_mount_t hpfs_mount; 68116271Sphkstatic vfs_root_t hpfs_root; 69116271Sphkstatic vfs_statfs_t hpfs_statfs; 70116271Sphkstatic vfs_unmount_t hpfs_unmount; 71116271Sphk 7254371Ssemenustatic int 73138487Sphkhpfs_cmount ( 74138487Sphk struct mntarg *ma, 75138487Sphk void *data, 76230725Smckusick uint64_t flags) 77138487Sphk{ 78138487Sphk struct hpfs_args args; 79213664Skib struct export_args exp; 80138487Sphk int error; 81138487Sphk 82138487Sphk error = copyin(data, (caddr_t)&args, sizeof (struct hpfs_args)); 83138487Sphk if (error) 84138487Sphk return (error); 85213664Skib vfs_oexport_conv(&args.export, &exp); 86138487Sphk 87138487Sphk ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN); 88213664Skib ma = mount_arg(ma, "export", &exp, sizeof(exp)); 89138487Sphk ma = mount_argf(ma, "uid", "%d", args.uid); 90138487Sphk ma = mount_argf(ma, "gid", "%d", args.gid); 91138487Sphk ma = mount_argf(ma, "mode", "%d", args.mode); 92138487Sphk if (args.flags & HPFSMNT_TABLES) { 93138487Sphk ma = mount_arg(ma, "d2u", args.d2u, sizeof args.d2u); 94138487Sphk ma = mount_arg(ma, "u2d", args.u2d, sizeof args.u2d); 95138487Sphk } 96138487Sphk 97138487Sphk error = kernel_mount(ma, flags); 98138487Sphk 99138487Sphk return (error); 100138487Sphk} 101138487Sphk 102138487Sphkstatic const char *hpfs_opts[] = { 103138487Sphk "from", "export", "uid", "gid", "mode", "d2u", "u2d", NULL 104138487Sphk}; 105138487Sphk 106138487Sphkstatic int 107191990Sattiliohpfs_mount (struct mount *mp) 10854371Ssemenu{ 109138487Sphk int err = 0, error; 11054371Ssemenu struct vnode *devvp; 111191990Sattilio struct thread *td; 112132902Sphk struct nameidata ndp; 113138487Sphk struct export_args export; 114138487Sphk char *from; 11554371Ssemenu 116191990Sattilio td = curthread; 117132902Sphk dprintf(("hpfs_omount():\n")); 11854371Ssemenu /* 11954371Ssemenu *** 12096755Strhodes * Mounting non-root filesystem or updating a filesystem 12154371Ssemenu *** 12254371Ssemenu */ 123138487Sphk if (vfs_filteropt(mp->mnt_optnew, hpfs_opts)) 124138487Sphk return (EINVAL); 12554371Ssemenu 126138487Sphk from = vfs_getopts(mp->mnt_optnew, "from", &error); 127138487Sphk if (error) 128138487Sphk return (error); 12954371Ssemenu 13054371Ssemenu /* 13154371Ssemenu * If updating, check whether changing from read-only to 13254371Ssemenu * read/write; if there is no device name, that's all we do. 13354371Ssemenu */ 13454371Ssemenu if (mp->mnt_flag & MNT_UPDATE) { 135132902Sphk dprintf(("hpfs_omount: MNT_UPDATE: ")); 13654371Ssemenu 137138487Sphk if (from == NULL) { 138138487Sphk error = vfs_copyopt(mp->mnt_optnew, "export", 139138487Sphk &export, sizeof export); 140138487Sphk if (error) 141138487Sphk return (error); 14254371Ssemenu dprintf(("export 0x%x\n",args.export.ex_flags)); 143138487Sphk err = vfs_export(mp, &export); 14454371Ssemenu if (err) { 145132902Sphk printf("hpfs_omount: vfs_export failed %d\n", 14654371Ssemenu err); 14754371Ssemenu } 14854371Ssemenu goto success; 14954371Ssemenu } else { 15054371Ssemenu dprintf(("name [FAILED]\n")); 15154371Ssemenu err = EINVAL; 15254371Ssemenu goto success; 15354371Ssemenu } 15454371Ssemenu dprintf(("\n")); 15554371Ssemenu } 15654371Ssemenu 15754371Ssemenu /* 15854371Ssemenu * Not an update, or updating the name: look up the name 15954371Ssemenu * and verify that it refers to a sensible block device. 16054371Ssemenu */ 161149720Sssouhlal NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td); 162132902Sphk err = namei(&ndp); 16354371Ssemenu if (err) { 16454371Ssemenu /* can't get devvp!*/ 16554371Ssemenu goto error_1; 16654371Ssemenu } 16754371Ssemenu 168132902Sphk devvp = ndp.ni_vp; 16954371Ssemenu 170149720Sssouhlal if (!vn_isdisk(devvp, &err)) { 171149720Sssouhlal vput(devvp); 172149720Sssouhlal return (err); 173149720Sssouhlal } 17454371Ssemenu 17554371Ssemenu /* 17654371Ssemenu ******************** 17754371Ssemenu * NEW MOUNT 17854371Ssemenu ******************** 17954371Ssemenu */ 18054371Ssemenu 18154371Ssemenu /* 18254371Ssemenu * Since this is a new mount, we want the names for 18354371Ssemenu * the device and the mount point copied in. If an 18473286Sadrian * error occurs, the mountpoint is discarded by the 185132902Sphk * upper level code. Note that vfs_omount() handles 18673286Sadrian * copying the mountpoint f_mntonname for us, so we 18773286Sadrian * don't have to do it here unless we want to set it 18873286Sadrian * to something other than "path" for some rason. 18954371Ssemenu */ 19054371Ssemenu /* Save "mounted from" info for mount point (NULL pad)*/ 191138487Sphk vfs_mountedfrom(mp, from); 19254371Ssemenu 193138487Sphk err = hpfs_mountfs(devvp, mp, td); 194149745Sssouhlal if (err) { 195149745Sssouhlal vrele(devvp); 196149745Sssouhlal goto error_1; 197149745Sssouhlal } 19854371Ssemenu 19954371Ssemenu goto success; 20054371Ssemenu 20154371Ssemenuerror_1: /* no state to back out*/ 202132902Sphk /* XXX: Missing NDFREE(&ndp, ...) */ 20354371Ssemenu 20454371Ssemenusuccess: 20554371Ssemenu return( err); 20654371Ssemenu} 20754371Ssemenu 20854371Ssemenu/* 20954371Ssemenu * Common code for mount and mountroot 21054371Ssemenu */ 21154371Ssemenuint 212138487Sphkhpfs_mountfs(devvp, mp, td) 21354371Ssemenu register struct vnode *devvp; 21454371Ssemenu struct mount *mp; 21586931Sjhb struct thread *td; 21654371Ssemenu{ 217138487Sphk int error, ronly, v; 21854371Ssemenu struct sublock *sup; 21954371Ssemenu struct spblock *spp; 22054371Ssemenu struct hpfsmount *hpmp; 22154371Ssemenu struct buf *bp = NULL; 22254371Ssemenu struct vnode *vp; 223130585Sphk struct cdev *dev = devvp->v_rdev; 224137040Sphk struct g_consumer *cp; 225137040Sphk struct bufobj *bo; 22654371Ssemenu 227137478Sphk if (mp->mnt_flag & MNT_ROOTFS) 228137478Sphk return (EOPNOTSUPP); 22954371Ssemenu dprintf(("hpfs_mountfs():\n")); 23054371Ssemenu ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 231137040Sphk /* XXX: use VOP_ACCESS to check FS perms */ 232137040Sphk DROP_GIANT(); 233137040Sphk g_topology_lock(); 234137040Sphk error = g_vfs_open(devvp, &cp, "hpfs", ronly ? 0 : 1); 235137040Sphk g_topology_unlock(); 236137040Sphk PICKUP_GIANT(); 237175294Sattilio VOP_UNLOCK(devvp, 0); 23854371Ssemenu if (error) 23954371Ssemenu return (error); 24054371Ssemenu 241137040Sphk bo = &devvp->v_bufobj; 242137040Sphk bo->bo_private = cp; 243137040Sphk bo->bo_ops = g_vfs_bufops; 244137040Sphk 24554371Ssemenu /* 24654371Ssemenu * Do actual mount 24754371Ssemenu */ 248111119Simp hpmp = malloc(sizeof(struct hpfsmount), M_HPFSMNT, M_WAITOK | M_ZERO); 24954371Ssemenu 250137040Sphk hpmp->hpm_cp = cp; 251137040Sphk hpmp->hpm_bo = bo; 252137040Sphk 25354371Ssemenu /* Read in SuperBlock */ 25454371Ssemenu error = bread(devvp, SUBLOCK, SUSIZE, NOCRED, &bp); 25554371Ssemenu if (error) 25654371Ssemenu goto failed; 25754371Ssemenu bcopy(bp->b_data, &hpmp->hpm_su, sizeof(struct sublock)); 25854371Ssemenu brelse(bp); bp = NULL; 25954371Ssemenu 26054371Ssemenu /* Read in SpareBlock */ 26154371Ssemenu error = bread(devvp, SPBLOCK, SPSIZE, NOCRED, &bp); 26254371Ssemenu if (error) 26354371Ssemenu goto failed; 26454371Ssemenu bcopy(bp->b_data, &hpmp->hpm_sp, sizeof(struct spblock)); 26554371Ssemenu brelse(bp); bp = NULL; 26654371Ssemenu 26754371Ssemenu sup = &hpmp->hpm_su; 26854371Ssemenu spp = &hpmp->hpm_sp; 26954371Ssemenu 27054371Ssemenu /* Check magic */ 27154371Ssemenu if (sup->su_magic != SU_MAGIC) { 27254371Ssemenu printf("hpfs_mountfs: SuperBlock MAGIC DOESN'T MATCH\n"); 27354371Ssemenu error = EINVAL; 27454371Ssemenu goto failed; 27554371Ssemenu } 27654371Ssemenu if (spp->sp_magic != SP_MAGIC) { 27754371Ssemenu printf("hpfs_mountfs: SpareBlock MAGIC DOESN'T MATCH\n"); 27854371Ssemenu error = EINVAL; 27954371Ssemenu goto failed; 28054371Ssemenu } 28154371Ssemenu 282172697Salfred mp->mnt_data = hpmp; 28354371Ssemenu hpmp->hpm_devvp = devvp; 28454371Ssemenu hpmp->hpm_dev = devvp->v_rdev; 28554371Ssemenu hpmp->hpm_mp = mp; 286233120Skevlo if (vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v) == 1) 287138487Sphk hpmp->hpm_uid = v; 288233120Skevlo if (vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v) == 1) 289138487Sphk hpmp->hpm_gid = v; 290233120Skevlo if (vfs_scanopt(mp->mnt_optnew, "mode", "%d", &v) == 1) 291138487Sphk hpmp->hpm_mode = v; 29254371Ssemenu 29354371Ssemenu error = hpfs_bminit(hpmp); 29454371Ssemenu if (error) 29554371Ssemenu goto failed; 29654371Ssemenu 297138487Sphk error = hpfs_cpinit(mp, hpmp); 29854371Ssemenu if (error) { 29954371Ssemenu hpfs_bmdeinit(hpmp); 30054371Ssemenu goto failed; 30154371Ssemenu } 30254371Ssemenu 303191990Sattilio error = hpfs_root(mp, LK_EXCLUSIVE, &vp); 30454371Ssemenu if (error) { 30554371Ssemenu hpfs_cpdeinit(hpmp); 30654371Ssemenu hpfs_bmdeinit(hpmp); 30754371Ssemenu goto failed; 30854371Ssemenu } 30954371Ssemenu 31054371Ssemenu vput(vp); 31154371Ssemenu 31254371Ssemenu mp->mnt_stat.f_fsid.val[0] = (long)dev2udev(dev); 31354371Ssemenu mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 31454371Ssemenu mp->mnt_maxsymlinklen = 0; 315162647Stegge MNT_ILOCK(mp); 31654371Ssemenu mp->mnt_flag |= MNT_LOCAL; 317162647Stegge MNT_IUNLOCK(mp); 31854371Ssemenu return (0); 31954371Ssemenu 32054371Ssemenufailed: 32154371Ssemenu if (bp) 32254371Ssemenu brelse (bp); 323172697Salfred mp->mnt_data = NULL; 324175137Sattilio DROP_GIANT(); 325175137Sattilio g_topology_lock(); 326183754Sattilio g_vfs_close(cp); 327175137Sattilio g_topology_unlock(); 328175137Sattilio PICKUP_GIANT(); 32954371Ssemenu return (error); 33054371Ssemenu} 33154371Ssemenu 33254371Ssemenustatic int 33354371Ssemenuhpfs_unmount( 33454371Ssemenu struct mount *mp, 335191990Sattilio int mntflags) 33654371Ssemenu{ 337187959Sbz int error, flags; 33854371Ssemenu register struct hpfsmount *hpmp = VFSTOHPFS(mp); 33954371Ssemenu 34054371Ssemenu dprintf(("hpfs_unmount():\n")); 34154371Ssemenu 34254371Ssemenu flags = 0; 34354371Ssemenu if(mntflags & MNT_FORCE) 34454371Ssemenu flags |= FORCECLOSE; 34554371Ssemenu 34654371Ssemenu dprintf(("hpfs_unmount: vflushing...\n")); 34754371Ssemenu 348191990Sattilio error = vflush(mp, 0, flags, curthread); 34954371Ssemenu if (error) { 35054371Ssemenu printf("hpfs_unmount: vflush failed: %d\n",error); 35154371Ssemenu return (error); 35254371Ssemenu } 35354371Ssemenu 354183754Sattilio vinvalbuf(hpmp->hpm_devvp, V_SAVE, 0, 0); 355175137Sattilio DROP_GIANT(); 356175137Sattilio g_topology_lock(); 357183754Sattilio g_vfs_close(hpmp->hpm_cp); 358175137Sattilio g_topology_unlock(); 359175137Sattilio PICKUP_GIANT(); 36054371Ssemenu vrele(hpmp->hpm_devvp); 36154371Ssemenu 36254371Ssemenu dprintf(("hpfs_umount: freeing memory...\n")); 36354371Ssemenu hpfs_cpdeinit(hpmp); 36454371Ssemenu hpfs_bmdeinit(hpmp); 365172697Salfred mp->mnt_data = NULL; 366162647Stegge MNT_ILOCK(mp); 36754371Ssemenu mp->mnt_flag &= ~MNT_LOCAL; 368162647Stegge MNT_IUNLOCK(mp); 369184205Sdes free(hpmp, M_HPFSMNT); 37054371Ssemenu 37154371Ssemenu return (0); 37254371Ssemenu} 37354371Ssemenu 37454371Ssemenustatic int 37554371Ssemenuhpfs_root( 37654371Ssemenu struct mount *mp, 377144058Sjeff int flags, 378191990Sattilio struct vnode **vpp) 37954371Ssemenu{ 38054371Ssemenu int error = 0; 38154371Ssemenu struct hpfsmount *hpmp = VFSTOHPFS(mp); 38254371Ssemenu 38354371Ssemenu dprintf(("hpfs_root():\n")); 38492462Smckusick error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, LK_EXCLUSIVE, vpp); 38554371Ssemenu if(error) { 38654371Ssemenu printf("hpfs_root: VFS_VGET failed: %d\n",error); 38754371Ssemenu return (error); 38854371Ssemenu } 38954371Ssemenu 39054371Ssemenu return (error); 39154371Ssemenu} 39254371Ssemenu 39354371Ssemenustatic int 39454371Ssemenuhpfs_statfs( 39554371Ssemenu struct mount *mp, 396191990Sattilio struct statfs *sbp) 39754371Ssemenu{ 39854371Ssemenu struct hpfsmount *hpmp = VFSTOHPFS(mp); 39954371Ssemenu 40054371Ssemenu dprintf(("hpfs_statfs(): HPFS%d.%d\n", 40154371Ssemenu hpmp->hpm_su.su_hpfsver, hpmp->hpm_su.su_fnctver)); 40254371Ssemenu 40354371Ssemenu sbp->f_type = mp->mnt_vfc->vfc_typenum; 40454371Ssemenu sbp->f_bsize = DEV_BSIZE; 40554371Ssemenu sbp->f_iosize = DEV_BSIZE; 40654371Ssemenu sbp->f_blocks = hpmp->hpm_su.su_btotal; 40754371Ssemenu sbp->f_bfree = sbp->f_bavail = hpmp->hpm_bavail; 40854371Ssemenu sbp->f_ffree = 0; 40954371Ssemenu sbp->f_files = 0; 41054371Ssemenu sbp->f_flags = mp->mnt_flag; 41154371Ssemenu 41254371Ssemenu return (0); 41354371Ssemenu} 41454371Ssemenu 41554371Ssemenu/*ARGSUSED*/ 41654371Ssemenustatic int 41754371Ssemenuhpfs_fhtovp( 41854371Ssemenu struct mount *mp, 41954371Ssemenu struct fid *fhp, 420222167Srmacklem int flags, 42154371Ssemenu struct vnode **vpp) 42254371Ssemenu{ 42354371Ssemenu struct vnode *nvp; 42454371Ssemenu struct hpfid *hpfhp = (struct hpfid *)fhp; 42554371Ssemenu int error; 42654371Ssemenu 42792462Smckusick if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, LK_EXCLUSIVE, &nvp)) != 0) { 42854371Ssemenu *vpp = NULLVP; 42954371Ssemenu return (error); 43054371Ssemenu } 43154371Ssemenu /* XXX as unlink/rmdir/mkdir/creat are not currently possible 43254371Ssemenu * with HPFS, we don't need to check anything else for now */ 43354371Ssemenu *vpp = nvp; 43454371Ssemenu 43554371Ssemenu return (0); 43654371Ssemenu} 43754371Ssemenu 43854371Ssemenustatic int 43954371Ssemenuhpfs_vget( 44054371Ssemenu struct mount *mp, 44154371Ssemenu ino_t ino, 44292462Smckusick int flags, 44354371Ssemenu struct vnode **vpp) 44454371Ssemenu{ 44554371Ssemenu struct hpfsmount *hpmp = VFSTOHPFS(mp); 44654371Ssemenu struct vnode *vp; 44754371Ssemenu struct hpfsnode *hp; 44854371Ssemenu struct buf *bp; 44954371Ssemenu int error; 45054371Ssemenu 45154371Ssemenu dprintf(("hpfs_vget(0x%x): ",ino)); 45254371Ssemenu 453143692Sphk error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); 454143619Sphk if (error || *vpp != NULL) 455143588Sphk return (error); 456143588Sphk 45754371Ssemenu *vpp = NULL; 45854371Ssemenu hp = NULL; 45954371Ssemenu vp = NULL; 46054371Ssemenu 46154371Ssemenu /* 46254371Ssemenu * We have to lock node creation for a while, 46354371Ssemenu * but then we have to call getnewvnode(), 46454371Ssemenu * this may cause hpfs_reclaim() to be called, 46554371Ssemenu * this may need to VOP_VGET() parent dir for 46654371Ssemenu * update reasons, and if parent is not in 46754371Ssemenu * hash, we have to lock node creation... 46854371Ssemenu * To solve this, we MALLOC, getnewvnode and init while 46954371Ssemenu * not locked (probability of node appearence 47054371Ssemenu * at that time is little, and anyway - we'll 47154371Ssemenu * check for it). 47254371Ssemenu */ 473184205Sdes hp = malloc(sizeof(struct hpfsnode), 474111119Simp M_HPFSNO, M_WAITOK); 47554371Ssemenu 476167497Stegge error = getnewvnode("hpfs", mp, &hpfs_vnodeops, &vp); 47754371Ssemenu if (error) { 47854371Ssemenu printf("hpfs_vget: can't get new vnode\n"); 479184205Sdes free(hp, M_HPFSNO); 48054371Ssemenu return (error); 48154371Ssemenu } 48254371Ssemenu 48354371Ssemenu dprintf(("prenew ")); 48454371Ssemenu 48554371Ssemenu vp->v_data = hp; 48654371Ssemenu 48754371Ssemenu if (ino == (ino_t)hpmp->hpm_su.su_rootfno) 488101308Sjeff vp->v_vflag |= VV_ROOT; 48954371Ssemenu 49071576Sjasone 49193818Sjhb mtx_init(&hp->h_interlock, "hpfsnode interlock", NULL, MTX_DEF); 49254371Ssemenu 49354371Ssemenu hp->h_flag = H_INVAL; 49454371Ssemenu hp->h_vp = vp; 49554371Ssemenu hp->h_hpmp = hpmp; 49654371Ssemenu hp->h_no = ino; 49754371Ssemenu hp->h_dev = hpmp->hpm_dev; 49854371Ssemenu hp->h_uid = hpmp->hpm_uid; 49954371Ssemenu hp->h_gid = hpmp->hpm_uid; 50054371Ssemenu hp->h_mode = hpmp->hpm_mode; 50154371Ssemenu hp->h_devvp = hpmp->hpm_devvp; 50254371Ssemenu 503175635Sattilio lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); 504167497Stegge error = insmntque(vp, mp); 505167497Stegge if (error != 0) { 506167497Stegge free(hp, M_HPFSNO); 507167497Stegge return (error); 508167497Stegge } 509175635Sattilio error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); 510143663Sphk if (error || *vpp != NULL) 51154371Ssemenu return (error); 51254371Ssemenu 51354371Ssemenu error = bread(hpmp->hpm_devvp, ino, FNODESIZE, NOCRED, &bp); 51454371Ssemenu if (error) { 51554371Ssemenu printf("hpfs_vget: can't read ino %d\n",ino); 51654371Ssemenu vput(vp); 51754371Ssemenu return (error); 51854371Ssemenu } 51954371Ssemenu bcopy(bp->b_data, &hp->h_fn, sizeof(struct fnode)); 52054371Ssemenu brelse(bp); 52154371Ssemenu 52254371Ssemenu if (hp->h_fn.fn_magic != FN_MAGIC) { 52354371Ssemenu printf("hpfs_vget: MAGIC DOESN'T MATCH\n"); 52454371Ssemenu vput(vp); 52554371Ssemenu return (EINVAL); 52654371Ssemenu } 52754371Ssemenu 52854371Ssemenu vp->v_type = hp->h_fn.fn_flag ? VDIR:VREG; 52954371Ssemenu hp->h_flag &= ~H_INVAL; 53054371Ssemenu 53154371Ssemenu *vpp = vp; 53254371Ssemenu 53354371Ssemenu return (0); 53454371Ssemenu} 53554371Ssemenu 53654371Ssemenustatic struct vfsops hpfs_vfsops = { 537116271Sphk .vfs_fhtovp = hpfs_fhtovp, 538138487Sphk .vfs_cmount = hpfs_cmount, 539138487Sphk .vfs_mount = hpfs_mount, 540116271Sphk .vfs_root = hpfs_root, 541116271Sphk .vfs_statfs = hpfs_statfs, 542116271Sphk .vfs_unmount = hpfs_unmount, 543116271Sphk .vfs_vget = hpfs_vget, 54454371Ssemenu}; 54554371SsemenuVFS_SET(hpfs_vfsops, hpfs, 0); 546