hpfs_vfsops.c revision 191990
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: head/sys/fs/hpfs/hpfs_vfsops.c 191990 2009-05-11 15:33:26Z attilio $ 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, 76191990Sattilio int flags) 77138487Sphk{ 78138487Sphk struct hpfs_args args; 79138487Sphk int error; 80138487Sphk 81138487Sphk error = copyin(data, (caddr_t)&args, sizeof (struct hpfs_args)); 82138487Sphk if (error) 83138487Sphk return (error); 84138487Sphk 85138487Sphk ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN); 86138487Sphk ma = mount_arg(ma, "export", &args.export, sizeof args.export); 87138487Sphk ma = mount_argf(ma, "uid", "%d", args.uid); 88138487Sphk ma = mount_argf(ma, "gid", "%d", args.gid); 89138487Sphk ma = mount_argf(ma, "mode", "%d", args.mode); 90138487Sphk if (args.flags & HPFSMNT_TABLES) { 91138487Sphk ma = mount_arg(ma, "d2u", args.d2u, sizeof args.d2u); 92138487Sphk ma = mount_arg(ma, "u2d", args.u2d, sizeof args.u2d); 93138487Sphk } 94138487Sphk 95138487Sphk error = kernel_mount(ma, flags); 96138487Sphk 97138487Sphk return (error); 98138487Sphk} 99138487Sphk 100138487Sphkstatic const char *hpfs_opts[] = { 101138487Sphk "from", "export", "uid", "gid", "mode", "d2u", "u2d", NULL 102138487Sphk}; 103138487Sphk 104138487Sphkstatic int 105191990Sattiliohpfs_mount (struct mount *mp) 10654371Ssemenu{ 107138487Sphk int err = 0, error; 10854371Ssemenu struct vnode *devvp; 109191990Sattilio struct thread *td; 110132902Sphk struct nameidata ndp; 111138487Sphk struct export_args export; 112138487Sphk char *from; 11354371Ssemenu 114191990Sattilio td = curthread; 115132902Sphk dprintf(("hpfs_omount():\n")); 11654371Ssemenu /* 11754371Ssemenu *** 11896755Strhodes * Mounting non-root filesystem or updating a filesystem 11954371Ssemenu *** 12054371Ssemenu */ 121138487Sphk if (vfs_filteropt(mp->mnt_optnew, hpfs_opts)) 122138487Sphk return (EINVAL); 12354371Ssemenu 124138487Sphk from = vfs_getopts(mp->mnt_optnew, "from", &error); 125138487Sphk if (error) 126138487Sphk return (error); 12754371Ssemenu 12854371Ssemenu /* 12954371Ssemenu * If updating, check whether changing from read-only to 13054371Ssemenu * read/write; if there is no device name, that's all we do. 13154371Ssemenu */ 13254371Ssemenu if (mp->mnt_flag & MNT_UPDATE) { 133132902Sphk dprintf(("hpfs_omount: MNT_UPDATE: ")); 13454371Ssemenu 135138487Sphk if (from == NULL) { 136138487Sphk error = vfs_copyopt(mp->mnt_optnew, "export", 137138487Sphk &export, sizeof export); 138138487Sphk if (error) 139138487Sphk return (error); 14054371Ssemenu dprintf(("export 0x%x\n",args.export.ex_flags)); 141138487Sphk err = vfs_export(mp, &export); 14254371Ssemenu if (err) { 143132902Sphk printf("hpfs_omount: vfs_export failed %d\n", 14454371Ssemenu err); 14554371Ssemenu } 14654371Ssemenu goto success; 14754371Ssemenu } else { 14854371Ssemenu dprintf(("name [FAILED]\n")); 14954371Ssemenu err = EINVAL; 15054371Ssemenu goto success; 15154371Ssemenu } 15254371Ssemenu dprintf(("\n")); 15354371Ssemenu } 15454371Ssemenu 15554371Ssemenu /* 15654371Ssemenu * Not an update, or updating the name: look up the name 15754371Ssemenu * and verify that it refers to a sensible block device. 15854371Ssemenu */ 159149720Sssouhlal NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td); 160132902Sphk err = namei(&ndp); 16154371Ssemenu if (err) { 16254371Ssemenu /* can't get devvp!*/ 16354371Ssemenu goto error_1; 16454371Ssemenu } 16554371Ssemenu 166132902Sphk devvp = ndp.ni_vp; 16754371Ssemenu 168149720Sssouhlal if (!vn_isdisk(devvp, &err)) { 169149720Sssouhlal vput(devvp); 170149720Sssouhlal return (err); 171149720Sssouhlal } 17254371Ssemenu 17354371Ssemenu /* 17454371Ssemenu ******************** 17554371Ssemenu * NEW MOUNT 17654371Ssemenu ******************** 17754371Ssemenu */ 17854371Ssemenu 17954371Ssemenu /* 18054371Ssemenu * Since this is a new mount, we want the names for 18154371Ssemenu * the device and the mount point copied in. If an 18273286Sadrian * error occurs, the mountpoint is discarded by the 183132902Sphk * upper level code. Note that vfs_omount() handles 18473286Sadrian * copying the mountpoint f_mntonname for us, so we 18573286Sadrian * don't have to do it here unless we want to set it 18673286Sadrian * to something other than "path" for some rason. 18754371Ssemenu */ 18854371Ssemenu /* Save "mounted from" info for mount point (NULL pad)*/ 189138487Sphk vfs_mountedfrom(mp, from); 19054371Ssemenu 191138487Sphk err = hpfs_mountfs(devvp, mp, td); 192149745Sssouhlal if (err) { 193149745Sssouhlal vrele(devvp); 194149745Sssouhlal goto error_1; 195149745Sssouhlal } 19654371Ssemenu 19754371Ssemenu goto success; 19854371Ssemenu 19954371Ssemenuerror_1: /* no state to back out*/ 200132902Sphk /* XXX: Missing NDFREE(&ndp, ...) */ 20154371Ssemenu 20254371Ssemenusuccess: 20354371Ssemenu return( err); 20454371Ssemenu} 20554371Ssemenu 20654371Ssemenu/* 20754371Ssemenu * Common code for mount and mountroot 20854371Ssemenu */ 20954371Ssemenuint 210138487Sphkhpfs_mountfs(devvp, mp, td) 21154371Ssemenu register struct vnode *devvp; 21254371Ssemenu struct mount *mp; 21386931Sjhb struct thread *td; 21454371Ssemenu{ 215138487Sphk int error, ronly, v; 21654371Ssemenu struct sublock *sup; 21754371Ssemenu struct spblock *spp; 21854371Ssemenu struct hpfsmount *hpmp; 21954371Ssemenu struct buf *bp = NULL; 22054371Ssemenu struct vnode *vp; 221130585Sphk struct cdev *dev = devvp->v_rdev; 222137040Sphk struct g_consumer *cp; 223137040Sphk struct bufobj *bo; 22454371Ssemenu 225137478Sphk if (mp->mnt_flag & MNT_ROOTFS) 226137478Sphk return (EOPNOTSUPP); 22754371Ssemenu dprintf(("hpfs_mountfs():\n")); 22854371Ssemenu ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 229137040Sphk /* XXX: use VOP_ACCESS to check FS perms */ 230137040Sphk DROP_GIANT(); 231137040Sphk g_topology_lock(); 232137040Sphk error = g_vfs_open(devvp, &cp, "hpfs", ronly ? 0 : 1); 233137040Sphk g_topology_unlock(); 234137040Sphk PICKUP_GIANT(); 235175294Sattilio VOP_UNLOCK(devvp, 0); 23654371Ssemenu if (error) 23754371Ssemenu return (error); 23854371Ssemenu 239137040Sphk bo = &devvp->v_bufobj; 240137040Sphk bo->bo_private = cp; 241137040Sphk bo->bo_ops = g_vfs_bufops; 242137040Sphk 24354371Ssemenu /* 24454371Ssemenu * Do actual mount 24554371Ssemenu */ 246111119Simp hpmp = malloc(sizeof(struct hpfsmount), M_HPFSMNT, M_WAITOK | M_ZERO); 24754371Ssemenu 248137040Sphk hpmp->hpm_cp = cp; 249137040Sphk hpmp->hpm_bo = bo; 250137040Sphk 25154371Ssemenu /* Read in SuperBlock */ 25254371Ssemenu error = bread(devvp, SUBLOCK, SUSIZE, NOCRED, &bp); 25354371Ssemenu if (error) 25454371Ssemenu goto failed; 25554371Ssemenu bcopy(bp->b_data, &hpmp->hpm_su, sizeof(struct sublock)); 25654371Ssemenu brelse(bp); bp = NULL; 25754371Ssemenu 25854371Ssemenu /* Read in SpareBlock */ 25954371Ssemenu error = bread(devvp, SPBLOCK, SPSIZE, NOCRED, &bp); 26054371Ssemenu if (error) 26154371Ssemenu goto failed; 26254371Ssemenu bcopy(bp->b_data, &hpmp->hpm_sp, sizeof(struct spblock)); 26354371Ssemenu brelse(bp); bp = NULL; 26454371Ssemenu 26554371Ssemenu sup = &hpmp->hpm_su; 26654371Ssemenu spp = &hpmp->hpm_sp; 26754371Ssemenu 26854371Ssemenu /* Check magic */ 26954371Ssemenu if (sup->su_magic != SU_MAGIC) { 27054371Ssemenu printf("hpfs_mountfs: SuperBlock MAGIC DOESN'T MATCH\n"); 27154371Ssemenu error = EINVAL; 27254371Ssemenu goto failed; 27354371Ssemenu } 27454371Ssemenu if (spp->sp_magic != SP_MAGIC) { 27554371Ssemenu printf("hpfs_mountfs: SpareBlock MAGIC DOESN'T MATCH\n"); 27654371Ssemenu error = EINVAL; 27754371Ssemenu goto failed; 27854371Ssemenu } 27954371Ssemenu 280172697Salfred mp->mnt_data = hpmp; 28154371Ssemenu hpmp->hpm_devvp = devvp; 28254371Ssemenu hpmp->hpm_dev = devvp->v_rdev; 28354371Ssemenu hpmp->hpm_mp = mp; 284138487Sphk if (1 == vfs_scanopt(mp->mnt_optnew, "uid", "%d", &v)) 285138487Sphk hpmp->hpm_uid = v; 286138487Sphk if (1 == vfs_scanopt(mp->mnt_optnew, "gid", "%d", &v)) 287138487Sphk hpmp->hpm_gid = v; 288138487Sphk if (1 == vfs_scanopt(mp->mnt_optnew, "mode", "%d", &v)) 289138487Sphk hpmp->hpm_mode = v; 29054371Ssemenu 29154371Ssemenu error = hpfs_bminit(hpmp); 29254371Ssemenu if (error) 29354371Ssemenu goto failed; 29454371Ssemenu 295138487Sphk error = hpfs_cpinit(mp, hpmp); 29654371Ssemenu if (error) { 29754371Ssemenu hpfs_bmdeinit(hpmp); 29854371Ssemenu goto failed; 29954371Ssemenu } 30054371Ssemenu 301191990Sattilio error = hpfs_root(mp, LK_EXCLUSIVE, &vp); 30254371Ssemenu if (error) { 30354371Ssemenu hpfs_cpdeinit(hpmp); 30454371Ssemenu hpfs_bmdeinit(hpmp); 30554371Ssemenu goto failed; 30654371Ssemenu } 30754371Ssemenu 30854371Ssemenu vput(vp); 30954371Ssemenu 31054371Ssemenu mp->mnt_stat.f_fsid.val[0] = (long)dev2udev(dev); 31154371Ssemenu mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 31254371Ssemenu mp->mnt_maxsymlinklen = 0; 313162647Stegge MNT_ILOCK(mp); 31454371Ssemenu mp->mnt_flag |= MNT_LOCAL; 315162647Stegge MNT_IUNLOCK(mp); 31654371Ssemenu return (0); 31754371Ssemenu 31854371Ssemenufailed: 31954371Ssemenu if (bp) 32054371Ssemenu brelse (bp); 321172697Salfred mp->mnt_data = NULL; 322175137Sattilio DROP_GIANT(); 323175137Sattilio g_topology_lock(); 324183754Sattilio g_vfs_close(cp); 325175137Sattilio g_topology_unlock(); 326175137Sattilio PICKUP_GIANT(); 32754371Ssemenu return (error); 32854371Ssemenu} 32954371Ssemenu 33054371Ssemenustatic int 33154371Ssemenuhpfs_unmount( 33254371Ssemenu struct mount *mp, 333191990Sattilio int mntflags) 33454371Ssemenu{ 335187959Sbz int error, flags; 33654371Ssemenu register struct hpfsmount *hpmp = VFSTOHPFS(mp); 33754371Ssemenu 33854371Ssemenu dprintf(("hpfs_unmount():\n")); 33954371Ssemenu 34054371Ssemenu flags = 0; 34154371Ssemenu if(mntflags & MNT_FORCE) 34254371Ssemenu flags |= FORCECLOSE; 34354371Ssemenu 34454371Ssemenu dprintf(("hpfs_unmount: vflushing...\n")); 34554371Ssemenu 346191990Sattilio error = vflush(mp, 0, flags, curthread); 34754371Ssemenu if (error) { 34854371Ssemenu printf("hpfs_unmount: vflush failed: %d\n",error); 34954371Ssemenu return (error); 35054371Ssemenu } 35154371Ssemenu 352183754Sattilio vinvalbuf(hpmp->hpm_devvp, V_SAVE, 0, 0); 353175137Sattilio DROP_GIANT(); 354175137Sattilio g_topology_lock(); 355183754Sattilio g_vfs_close(hpmp->hpm_cp); 356175137Sattilio g_topology_unlock(); 357175137Sattilio PICKUP_GIANT(); 35854371Ssemenu vrele(hpmp->hpm_devvp); 35954371Ssemenu 36054371Ssemenu dprintf(("hpfs_umount: freeing memory...\n")); 36154371Ssemenu hpfs_cpdeinit(hpmp); 36254371Ssemenu hpfs_bmdeinit(hpmp); 363172697Salfred mp->mnt_data = NULL; 364162647Stegge MNT_ILOCK(mp); 36554371Ssemenu mp->mnt_flag &= ~MNT_LOCAL; 366162647Stegge MNT_IUNLOCK(mp); 367184205Sdes free(hpmp, M_HPFSMNT); 36854371Ssemenu 36954371Ssemenu return (0); 37054371Ssemenu} 37154371Ssemenu 37254371Ssemenustatic int 37354371Ssemenuhpfs_root( 37454371Ssemenu struct mount *mp, 375144058Sjeff int flags, 376191990Sattilio struct vnode **vpp) 37754371Ssemenu{ 37854371Ssemenu int error = 0; 37954371Ssemenu struct hpfsmount *hpmp = VFSTOHPFS(mp); 38054371Ssemenu 38154371Ssemenu dprintf(("hpfs_root():\n")); 38292462Smckusick error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, LK_EXCLUSIVE, vpp); 38354371Ssemenu if(error) { 38454371Ssemenu printf("hpfs_root: VFS_VGET failed: %d\n",error); 38554371Ssemenu return (error); 38654371Ssemenu } 38754371Ssemenu 38854371Ssemenu return (error); 38954371Ssemenu} 39054371Ssemenu 39154371Ssemenustatic int 39254371Ssemenuhpfs_statfs( 39354371Ssemenu struct mount *mp, 394191990Sattilio struct statfs *sbp) 39554371Ssemenu{ 39654371Ssemenu struct hpfsmount *hpmp = VFSTOHPFS(mp); 39754371Ssemenu 39854371Ssemenu dprintf(("hpfs_statfs(): HPFS%d.%d\n", 39954371Ssemenu hpmp->hpm_su.su_hpfsver, hpmp->hpm_su.su_fnctver)); 40054371Ssemenu 40154371Ssemenu sbp->f_type = mp->mnt_vfc->vfc_typenum; 40254371Ssemenu sbp->f_bsize = DEV_BSIZE; 40354371Ssemenu sbp->f_iosize = DEV_BSIZE; 40454371Ssemenu sbp->f_blocks = hpmp->hpm_su.su_btotal; 40554371Ssemenu sbp->f_bfree = sbp->f_bavail = hpmp->hpm_bavail; 40654371Ssemenu sbp->f_ffree = 0; 40754371Ssemenu sbp->f_files = 0; 40854371Ssemenu sbp->f_flags = mp->mnt_flag; 40954371Ssemenu 41054371Ssemenu return (0); 41154371Ssemenu} 41254371Ssemenu 41354371Ssemenu/*ARGSUSED*/ 41454371Ssemenustatic int 41554371Ssemenuhpfs_fhtovp( 41654371Ssemenu struct mount *mp, 41754371Ssemenu struct fid *fhp, 41854371Ssemenu struct vnode **vpp) 41954371Ssemenu{ 42054371Ssemenu struct vnode *nvp; 42154371Ssemenu struct hpfid *hpfhp = (struct hpfid *)fhp; 42254371Ssemenu int error; 42354371Ssemenu 42492462Smckusick if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, LK_EXCLUSIVE, &nvp)) != 0) { 42554371Ssemenu *vpp = NULLVP; 42654371Ssemenu return (error); 42754371Ssemenu } 42854371Ssemenu /* XXX as unlink/rmdir/mkdir/creat are not currently possible 42954371Ssemenu * with HPFS, we don't need to check anything else for now */ 43054371Ssemenu *vpp = nvp; 43154371Ssemenu 43254371Ssemenu return (0); 43354371Ssemenu} 43454371Ssemenu 43554371Ssemenustatic int 43654371Ssemenuhpfs_vget( 43754371Ssemenu struct mount *mp, 43854371Ssemenu ino_t ino, 43992462Smckusick int flags, 44054371Ssemenu struct vnode **vpp) 44154371Ssemenu{ 44254371Ssemenu struct hpfsmount *hpmp = VFSTOHPFS(mp); 44354371Ssemenu struct vnode *vp; 44454371Ssemenu struct hpfsnode *hp; 44554371Ssemenu struct buf *bp; 44654371Ssemenu int error; 44754371Ssemenu 44854371Ssemenu dprintf(("hpfs_vget(0x%x): ",ino)); 44954371Ssemenu 450143692Sphk error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); 451143619Sphk if (error || *vpp != NULL) 452143588Sphk return (error); 453143588Sphk 45454371Ssemenu *vpp = NULL; 45554371Ssemenu hp = NULL; 45654371Ssemenu vp = NULL; 45754371Ssemenu 45854371Ssemenu /* 45954371Ssemenu * We have to lock node creation for a while, 46054371Ssemenu * but then we have to call getnewvnode(), 46154371Ssemenu * this may cause hpfs_reclaim() to be called, 46254371Ssemenu * this may need to VOP_VGET() parent dir for 46354371Ssemenu * update reasons, and if parent is not in 46454371Ssemenu * hash, we have to lock node creation... 46554371Ssemenu * To solve this, we MALLOC, getnewvnode and init while 46654371Ssemenu * not locked (probability of node appearence 46754371Ssemenu * at that time is little, and anyway - we'll 46854371Ssemenu * check for it). 46954371Ssemenu */ 470184205Sdes hp = malloc(sizeof(struct hpfsnode), 471111119Simp M_HPFSNO, M_WAITOK); 47254371Ssemenu 473167497Stegge error = getnewvnode("hpfs", mp, &hpfs_vnodeops, &vp); 47454371Ssemenu if (error) { 47554371Ssemenu printf("hpfs_vget: can't get new vnode\n"); 476184205Sdes free(hp, M_HPFSNO); 47754371Ssemenu return (error); 47854371Ssemenu } 47954371Ssemenu 48054371Ssemenu dprintf(("prenew ")); 48154371Ssemenu 48254371Ssemenu vp->v_data = hp; 48354371Ssemenu 48454371Ssemenu if (ino == (ino_t)hpmp->hpm_su.su_rootfno) 485101308Sjeff vp->v_vflag |= VV_ROOT; 48654371Ssemenu 48771576Sjasone 48893818Sjhb mtx_init(&hp->h_interlock, "hpfsnode interlock", NULL, MTX_DEF); 48954371Ssemenu 49054371Ssemenu hp->h_flag = H_INVAL; 49154371Ssemenu hp->h_vp = vp; 49254371Ssemenu hp->h_hpmp = hpmp; 49354371Ssemenu hp->h_no = ino; 49454371Ssemenu hp->h_dev = hpmp->hpm_dev; 49554371Ssemenu hp->h_uid = hpmp->hpm_uid; 49654371Ssemenu hp->h_gid = hpmp->hpm_uid; 49754371Ssemenu hp->h_mode = hpmp->hpm_mode; 49854371Ssemenu hp->h_devvp = hpmp->hpm_devvp; 49954371Ssemenu 500175635Sattilio lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); 501167497Stegge error = insmntque(vp, mp); 502167497Stegge if (error != 0) { 503167497Stegge free(hp, M_HPFSNO); 504167497Stegge return (error); 505167497Stegge } 506175635Sattilio error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); 507143663Sphk if (error || *vpp != NULL) 50854371Ssemenu return (error); 50954371Ssemenu 51054371Ssemenu error = bread(hpmp->hpm_devvp, ino, FNODESIZE, NOCRED, &bp); 51154371Ssemenu if (error) { 51254371Ssemenu printf("hpfs_vget: can't read ino %d\n",ino); 51354371Ssemenu vput(vp); 51454371Ssemenu return (error); 51554371Ssemenu } 51654371Ssemenu bcopy(bp->b_data, &hp->h_fn, sizeof(struct fnode)); 51754371Ssemenu brelse(bp); 51854371Ssemenu 51954371Ssemenu if (hp->h_fn.fn_magic != FN_MAGIC) { 52054371Ssemenu printf("hpfs_vget: MAGIC DOESN'T MATCH\n"); 52154371Ssemenu vput(vp); 52254371Ssemenu return (EINVAL); 52354371Ssemenu } 52454371Ssemenu 52554371Ssemenu vp->v_type = hp->h_fn.fn_flag ? VDIR:VREG; 52654371Ssemenu hp->h_flag &= ~H_INVAL; 52754371Ssemenu 52854371Ssemenu *vpp = vp; 52954371Ssemenu 53054371Ssemenu return (0); 53154371Ssemenu} 53254371Ssemenu 53354371Ssemenustatic struct vfsops hpfs_vfsops = { 534116271Sphk .vfs_fhtovp = hpfs_fhtovp, 535138487Sphk .vfs_cmount = hpfs_cmount, 536138487Sphk .vfs_mount = hpfs_mount, 537116271Sphk .vfs_root = hpfs_root, 538116271Sphk .vfs_statfs = hpfs_statfs, 539116271Sphk .vfs_unmount = hpfs_unmount, 540116271Sphk .vfs_vget = hpfs_vget, 54154371Ssemenu}; 54254371SsemenuVFS_SET(hpfs_vfsops, hpfs, 0); 543