File:  [DragonFly] / src / sys / vfs / hpfs / hpfs_vfsops.c
Revision 1.15: download - view: text, annotated - select for diffs
Sat Apr 24 04:32:04 2004 UTC (9 years, 11 months ago) by drhodus
Branches: MAIN
CVS tags: HEAD
Remove the VREF() macro and uses of it.
Remove uses of 0x20 before ^I inside vnode.h

    1: /*-
    2:  * Copyright (c) 1998, 1999 Semen Ustimenko (semenu@FreeBSD.org)
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer.
   10:  * 2. Redistributions in binary form must reproduce the above copyright
   11:  *    notice, this list of conditions and the following disclaimer in the
   12:  *    documentation and/or other materials provided with the distribution.
   13:  *
   14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24:  * SUCH DAMAGE.
   25:  *
   26:  * $FreeBSD: src/sys/fs/hpfs/hpfs_vfsops.c,v 1.3.2.2 2001/12/25 01:44:45 dillon Exp $
   27:  * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.15 2004/04/24 04:32:04 drhodus Exp $
   28:  */
   29: 
   30: 
   31: #include <sys/param.h>
   32: #include <sys/systm.h>
   33: #include <sys/namei.h>
   34: #include <sys/conf.h>
   35: #include <sys/proc.h>
   36: #include <sys/kernel.h>
   37: #include <sys/vnode.h>
   38: #include <sys/mount.h>
   39: #include <sys/buf.h>
   40: #include <sys/fcntl.h>
   41: #include <sys/malloc.h>
   42: 
   43: #include <vm/vm.h>
   44: #include <vm/vm_param.h>
   45: #if defined(__NetBSD__)
   46: #include <vm/vm_prot.h>
   47: #endif
   48: #include <vm/vm_page.h>
   49: #include <vm/vm_object.h>
   50: #include <vm/vm_extern.h>
   51: #include <sys/buf2.h>
   52: 
   53: #if defined(__NetBSD__)
   54: #include <miscfs/specfs/specdev.h>
   55: #endif
   56: 
   57: #include "hpfs.h"
   58: #include "hpfsmount.h"
   59: #include "hpfs_subr.h"
   60: 
   61: #if defined(__DragonFly__)
   62: MALLOC_DEFINE(M_HPFSMNT, "HPFS mount", "HPFS mount structure");
   63: MALLOC_DEFINE(M_HPFSNO, "HPFS node", "HPFS node structure");
   64: #endif
   65: 
   66: static int	hpfs_root (struct mount *, struct vnode **);
   67: static int	hpfs_statfs (struct mount *, struct statfs *,
   68: 				 struct thread *);
   69: static int	hpfs_unmount (struct mount *, int, struct thread *);
   70: static int	hpfs_vget (struct mount *mp, ino_t ino,
   71: 			       struct vnode **vpp);
   72: static int	hpfs_mountfs (struct vnode *, struct mount *, 
   73: 				  struct hpfs_args *, struct thread *);
   74: static int	hpfs_vptofh (struct vnode *, struct fid *);
   75: static int	hpfs_fhtovp (struct mount *, struct fid *,
   76: 				 struct vnode **);
   77: 
   78: #if !defined(__DragonFly__)
   79: static int	hpfs_quotactl (struct mount *, int, uid_t, caddr_t,
   80: 				   struct proc *);
   81: static int	hpfs_start (struct mount *, int, struct proc *);
   82: static int	hpfs_sync (struct mount *, int, struct ucred *,
   83: 			       struct proc *);
   84: #endif
   85: 
   86: #if defined(__DragonFly__)
   87: struct sockaddr;
   88: static int	hpfs_mount (struct mount *, char *, caddr_t,
   89: 				struct nameidata *, struct thread *);
   90: static int	hpfs_init (struct vfsconf *);
   91: static int	hpfs_checkexp (struct mount *, struct sockaddr *,
   92: 				   int *, struct ucred **);
   93: #else /* defined(__NetBSD__) */
   94: static int	hpfs_mount (struct mount *, const char *, void *,
   95: 				struct nameidata *, struct proc *);
   96: static void	hpfs_init (void);
   97: static int	hpfs_mountroot (void);
   98: static int	hpfs_sysctl (int *, u_int, void *, size_t *, void *,
   99: 				 size_t, struct proc *);
  100: static int	hpfs_checkexp (struct mount *, struct mbuf *,
  101: 				   int *, struct ucred **);
  102: #endif
  103: 
  104: /*ARGSUSED*/
  105: static int
  106: hpfs_checkexp(struct mount *mp,
  107: #if defined(__DragonFly__)
  108: 	      struct sockaddr *nam,
  109: #else /* defined(__NetBSD__) */
  110: 	      struct mbuf *nam,
  111: #endif
  112: 	      int *exflagsp, struct ucred **credanonp)
  113: {
  114: 	struct netcred *np;
  115: 	struct hpfsmount *hpm = VFSTOHPFS(mp);
  116: 
  117: 	/*
  118: 	 * Get the export permission structure for this <mp, client> tuple.
  119: 	 */
  120: 	np = vfs_export_lookup(mp, &hpm->hpm_export, nam);
  121: 	if (np == NULL)
  122: 		return (EACCES);
  123: 
  124: 	*exflagsp = np->netc_exflags;
  125: 	*credanonp = &np->netc_anon;
  126: 	return (0);
  127: }
  128: 
  129: #if !defined(__DragonFly__)
  130: /*ARGSUSED*/
  131: static int
  132: hpfs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  133: 	    size_t newlen, struct thread *td)
  134: {
  135: 	return (EINVAL);
  136: }
  137: 
  138: static int
  139: hpfs_mountroot(void)
  140: {
  141: 	return (EINVAL);
  142: }
  143: #endif
  144: 
  145: #if defined(__DragonFly__)
  146: static int
  147: hpfs_init(struct vfsconf *vcp)
  148: #else /* defined(__NetBSD__) */
  149: static void
  150: hpfs_init(void)
  151: #endif
  152: {
  153: 	dprintf(("hpfs_init():\n"));
  154: 	
  155: 	hpfs_hphashinit();
  156: #if defined(__DragonFly__)
  157: 	return 0;
  158: #endif
  159: }
  160: 
  161: static int
  162: hpfs_mount(struct mount *mp,
  163: #if defined(__DragonFly__)
  164: 	   char *path, caddr_t data,
  165: #else /* defined(__NetBSD__) */
  166: 	   const char *path, void *data,
  167: #endif
  168: 	   struct nameidata *ndp, struct thread *td)
  169: {
  170: 	u_int		size;
  171: 	int		err = 0;
  172: 	struct vnode	*devvp;
  173: 	struct hpfs_args args;
  174: 	struct hpfsmount *hpmp = 0;
  175: 
  176: 	dprintf(("hpfs_mount():\n"));
  177: 	/*
  178: 	 ***
  179: 	 * Mounting non-root file system or updating a file system
  180: 	 ***
  181: 	 */
  182: 
  183: 	/* copy in user arguments*/
  184: 	err = copyin(data, (caddr_t)&args, sizeof (struct hpfs_args));
  185: 	if (err)
  186: 		goto error_1;		/* can't get arguments*/
  187: 
  188: 	/*
  189: 	 * If updating, check whether changing from read-only to
  190: 	 * read/write; if there is no device name, that's all we do.
  191: 	 */
  192: 	if (mp->mnt_flag & MNT_UPDATE) {
  193: 		dprintf(("hpfs_mount: MNT_UPDATE: "));
  194: 
  195: 		hpmp = VFSTOHPFS(mp);
  196: 
  197: 		if (args.fspec == 0) {
  198: 			dprintf(("export 0x%x\n",args.export.ex_flags));
  199: 			err = vfs_export(mp, &hpmp->hpm_export, &args.export);
  200: 			if (err) {
  201: 				printf("hpfs_mount: vfs_export failed %d\n",
  202: 					err);
  203: 			}
  204: 			goto success;
  205: 		} else {
  206: 			dprintf(("name [FAILED]\n"));
  207: 			err = EINVAL;
  208: 			goto success;
  209: 		}
  210: 		dprintf(("\n"));
  211: 	}
  212: 
  213: 	/*
  214: 	 * Not an update, or updating the name: look up the name
  215: 	 * and verify that it refers to a sensible block device.
  216: 	 */
  217: 	NDINIT(ndp, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, args.fspec, td);
  218: 	err = namei(ndp);
  219: 	if (err) {
  220: 		/* can't get devvp!*/
  221: 		goto error_1;
  222: 	}
  223: 
  224: 	devvp = ndp->ni_vp;
  225: 
  226: #if defined(__DragonFly__)
  227: 	if (!vn_isdisk(devvp, &err)) 
  228: 		goto error_2;
  229: #else /* defined(__NetBSD__) */
  230: 	if (devvp->v_type != VBLK) {
  231: 		err = ENOTBLK;
  232: 		goto error_2;
  233: 	}
  234: 	if (major(devvp->v_rdev) >= nblkdev) {
  235: 		err = ENXIO;
  236: 		goto error_2;
  237: 	}
  238: #endif
  239: 
  240: 	/*
  241: 	 ********************
  242: 	 * NEW MOUNT
  243: 	 ********************
  244: 	 */
  245: 
  246: 	/*
  247: 	 * Since this is a new mount, we want the names for
  248: 	 * the device and the mount point copied in.  If an
  249: 	 * error occurs,  the mountpoint is discarded by the
  250: 	 * upper level code.
  251: 	 */
  252: 	/* Save "last mounted on" info for mount point (NULL pad)*/
  253: 	copyinstr(	path,				/* mount point*/
  254: 			mp->mnt_stat.f_mntonname,	/* save area*/
  255: 			MNAMELEN - 1,			/* max size*/
  256: 			&size);				/* real size*/
  257: 	bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
  258: 
  259: 	/* Save "mounted from" info for mount point (NULL pad)*/
  260: 	copyinstr(	args.fspec,			/* device name*/
  261: 			mp->mnt_stat.f_mntfromname,	/* save area*/
  262: 			MNAMELEN - 1,			/* max size*/
  263: 			&size);				/* real size*/
  264: 	bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
  265: 
  266: 	err = hpfs_mountfs(devvp, mp, &args, td);
  267: 	if (err)
  268: 		goto error_2;
  269: 
  270: 	/*
  271: 	 * Initialize FS stat information in mount struct; uses both
  272: 	 * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
  273: 	 *
  274: 	 * This code is common to root and non-root mounts
  275: 	 */
  276: 	(void)VFS_STATFS(mp, &mp->mnt_stat, td);
  277: 
  278: 	goto success;
  279: 
  280: 
  281: error_2:	/* error with devvp held*/
  282: 
  283: 	/* release devvp before failing*/
  284: 	vrele(devvp);
  285: 
  286: error_1:	/* no state to back out*/
  287: 
  288: success:
  289: 	return( err);
  290: }
  291: 
  292: /*
  293:  * Common code for mount and mountroot
  294:  */
  295: int
  296: hpfs_mountfs(struct vnode *devvp, struct mount *mp, struct hpfs_args *argsp,
  297: 	     struct thread *td)
  298: {
  299: 	int error, ncount, ronly;
  300: 	struct sublock *sup;
  301: 	struct spblock *spp;
  302: 	struct hpfsmount *hpmp;
  303: 	struct buf *bp = NULL;
  304: 	struct vnode *vp;
  305: 	dev_t dev = devvp->v_rdev;
  306: 
  307: 	dprintf(("hpfs_mountfs():\n"));
  308: 	/*
  309: 	 * Disallow multiple mounts of the same device.
  310: 	 * Disallow mounting of a device that is currently in use
  311: 	 * (except for root, which might share swap device for miniroot).
  312: 	 * Flush out any old buffers remaining from a previous use.
  313: 	 */
  314: 	error = vfs_mountedon(devvp);
  315: 	if (error)
  316: 		return (error);
  317: 	ncount = vcount(devvp);
  318: #if defined(__DragonFly__)
  319: 	if (devvp->v_object)
  320: 		ncount -= 1;
  321: #endif
  322: 	if (ncount > 1 && devvp != rootvp)
  323: 		return (EBUSY);
  324: 
  325: #if defined(__DragonFly__)
  326: 	VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  327: 	error = vinvalbuf(devvp, V_SAVE, td, 0, 0);
  328: 	VOP__UNLOCK(devvp, 0, td);
  329: #else
  330: 	error = vinvalbuf(devvp, V_SAVE, td, 0, 0);
  331: #endif
  332: 	if (error)
  333: 		return (error);
  334: 
  335: 	ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
  336: 	VN_LOCK(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  337: 	error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, td);
  338: 	VOP__UNLOCK(devvp, 0, td);
  339: 	if (error)
  340: 		return (error);
  341: 
  342: 	/*
  343: 	 * Do actual mount
  344: 	 */
  345: 	hpmp = malloc(sizeof(struct hpfsmount), M_HPFSMNT, M_WAITOK);
  346: 	bzero(hpmp, sizeof(struct hpfsmount));
  347: 
  348: 	/* Read in SuperBlock */
  349: 	error = bread(devvp, SUBLOCK, SUSIZE, &bp);
  350: 	if (error)
  351: 		goto failed;
  352: 	bcopy(bp->b_data, &hpmp->hpm_su, sizeof(struct sublock));
  353: 	brelse(bp); bp = NULL;
  354: 
  355: 	/* Read in SpareBlock */
  356: 	error = bread(devvp, SPBLOCK, SPSIZE, &bp);
  357: 	if (error)
  358: 		goto failed;
  359: 	bcopy(bp->b_data, &hpmp->hpm_sp, sizeof(struct spblock));
  360: 	brelse(bp); bp = NULL;
  361: 
  362: 	sup = &hpmp->hpm_su;
  363: 	spp = &hpmp->hpm_sp;
  364: 
  365: 	/* Check magic */
  366: 	if (sup->su_magic != SU_MAGIC) {
  367: 		printf("hpfs_mountfs: SuperBlock MAGIC DOESN'T MATCH\n");
  368: 		error = EINVAL;
  369: 		goto failed;
  370: 	}
  371: 	if (spp->sp_magic != SP_MAGIC) {
  372: 		printf("hpfs_mountfs: SpareBlock MAGIC DOESN'T MATCH\n");
  373: 		error = EINVAL;
  374: 		goto failed;
  375: 	}
  376: 
  377: 	mp->mnt_data = (qaddr_t)hpmp;
  378: 	hpmp->hpm_devvp = devvp;
  379: 	hpmp->hpm_dev = devvp->v_rdev;
  380: 	hpmp->hpm_mp = mp;
  381: 	hpmp->hpm_uid = argsp->uid;
  382: 	hpmp->hpm_gid = argsp->gid;
  383: 	hpmp->hpm_mode = argsp->mode;
  384: 
  385: 	error = hpfs_bminit(hpmp);
  386: 	if (error)
  387: 		goto failed;
  388: 
  389: 	error = hpfs_cpinit(hpmp, argsp);
  390: 	if (error) {
  391: 		hpfs_bmdeinit(hpmp);
  392: 		goto failed;
  393: 	}
  394: 
  395: 	error = hpfs_root(mp, &vp);
  396: 	if (error) {
  397: 		hpfs_cpdeinit(hpmp);
  398: 		hpfs_bmdeinit(hpmp);
  399: 		goto failed;
  400: 	}
  401: 
  402: 	vput(vp);
  403: 
  404: #if defined(__DragonFly__)
  405: 	mp->mnt_stat.f_fsid.val[0] = (long)dev2udev(dev);
  406: 	mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
  407: #else
  408: 	mp->mnt_stat.f_fsid.val[0] = (long)dev;
  409: 	mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_HPFS);
  410: #endif
  411: 	mp->mnt_maxsymlinklen = 0;
  412: 	mp->mnt_flag |= MNT_LOCAL;
  413: 	devvp->v_specmountpoint = mp;
  414: 	return (0);
  415: 
  416: failed:
  417: 	if (bp)
  418: 		brelse (bp);
  419: 	mp->mnt_data = (qaddr_t)NULL;
  420: #if defined(__DragonFly__)
  421: 	devvp->v_specmountpoint = NULL;
  422: #else
  423: 	devvp->v_specflags &= ~SI_MOUNTEDON;
  424: #endif
  425: 	(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, td);
  426: 	return (error);
  427: }
  428: 
  429: #if !defined(__DragonFly__)
  430: static int
  431: hpfs_start(struct mount *mp, int flags, struct thread *td)
  432: {
  433: 	return (0);
  434: }
  435: #endif
  436: 
  437: static int
  438: hpfs_unmount(struct mount *mp, int mntflags, struct thread *td)
  439: {
  440: 	int error, flags, ronly;
  441: 	struct hpfsmount *hpmp = VFSTOHPFS(mp);
  442: 
  443: 	dprintf(("hpfs_unmount():\n"));
  444: 
  445: 	ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
  446: 
  447: 	flags = 0;
  448: 	if(mntflags & MNT_FORCE)
  449: 		flags |= FORCECLOSE;
  450: 
  451: 	dprintf(("hpfs_unmount: vflushing...\n"));
  452: 	
  453: 	error = vflush(mp, 0, flags);
  454: 	if (error) {
  455: 		printf("hpfs_unmount: vflush failed: %d\n",error);
  456: 		return (error);
  457: 	}
  458: 
  459: #if defined(__DragonFly__)
  460: 	hpmp->hpm_devvp->v_specmountpoint = NULL;
  461: #else
  462: 	hpmp->hpm_devvp->v_specflags &= ~SI_MOUNTEDON;
  463: #endif
  464: 
  465: 	vinvalbuf(hpmp->hpm_devvp, V_SAVE, td, 0, 0);
  466: 	error = VOP_CLOSE(hpmp->hpm_devvp, ronly ? FREAD : FREAD|FWRITE, td);
  467: 
  468: 	vrele(hpmp->hpm_devvp);
  469: 
  470: 	dprintf(("hpfs_umount: freeing memory...\n"));
  471: 	hpfs_cpdeinit(hpmp);
  472: 	hpfs_bmdeinit(hpmp);
  473: 	mp->mnt_data = (qaddr_t)0;
  474: 	mp->mnt_flag &= ~MNT_LOCAL;
  475: 	FREE(hpmp, M_HPFSMNT);
  476: 
  477: 	return (0);
  478: }
  479: 
  480: static int
  481: hpfs_root(struct mount *mp, struct vnode **vpp)
  482: {
  483: 	int error = 0;
  484: 	struct hpfsmount *hpmp = VFSTOHPFS(mp);
  485: 
  486: 	dprintf(("hpfs_root():\n"));
  487: 	error = VFS_VGET(mp, (ino_t)hpmp->hpm_su.su_rootfno, vpp);
  488: 	if(error) {
  489: 		printf("hpfs_root: VFS_VGET failed: %d\n",error);
  490: 		return (error);
  491: 	}
  492: 
  493: 	return (error);
  494: }
  495: 
  496: static int
  497: hpfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
  498: {
  499: 	struct hpfsmount *hpmp = VFSTOHPFS(mp);
  500: 
  501: 	dprintf(("hpfs_statfs(): HPFS%d.%d\n",
  502: 		hpmp->hpm_su.su_hpfsver, hpmp->hpm_su.su_fnctver));
  503: 
  504: #if defined(__DragonFly__)
  505: 	sbp->f_type = mp->mnt_vfc->vfc_typenum;
  506: #else /* defined(__NetBSD__) */
  507: 	sbp->f_type = 0;
  508: #endif
  509: 	sbp->f_bsize = DEV_BSIZE;
  510: 	sbp->f_iosize = DEV_BSIZE;
  511: 	sbp->f_blocks = hpmp->hpm_su.su_btotal;
  512: 	sbp->f_bfree = sbp->f_bavail = hpmp->hpm_bavail;
  513: 	sbp->f_ffree = 0;
  514: 	sbp->f_files = 0;
  515: 	if (sbp != &mp->mnt_stat) {
  516: 		bcopy((caddr_t)mp->mnt_stat.f_mntonname,
  517: 			(caddr_t)&sbp->f_mntonname[0], MNAMELEN);
  518: 		bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
  519: 			(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
  520: 	}
  521: 	sbp->f_flags = mp->mnt_flag;
  522: 	
  523: 	return (0);
  524: }
  525: 
  526: #if !defined(__DragonFly__)
  527: static int
  528: hpfs_sync(struct mount *mp, int waitfor, struct ucred *cred,
  529: 	  struct thread *td)
  530: {
  531: 	return (0);
  532: }
  533: 
  534: static int
  535: hpfs_quotactl(struct mount *mp, int cmds, uid_t uid, caddr_t arg,
  536: 	      struct thread *td)
  537: {
  538: 	printf("hpfs_quotactl():\n");
  539: 	return (EOPNOTSUPP);
  540: }
  541: #endif
  542: 
  543: /*ARGSUSED*/
  544: static int
  545: hpfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
  546: {
  547: 	struct vnode *nvp;
  548: 	struct hpfid *hpfhp = (struct hpfid *)fhp;
  549: 	int error;
  550: 
  551: 	if ((error = VFS_VGET(mp, hpfhp->hpfid_ino, &nvp)) != 0) {
  552: 		*vpp = NULLVP;
  553: 		return (error);
  554: 	}
  555: 	/* XXX as unlink/rmdir/mkdir/creat are not currently possible
  556: 	 * with HPFS, we don't need to check anything else for now */
  557: 	*vpp = nvp;
  558: 
  559: 	return (0);
  560: }
  561: 
  562: static int
  563: hpfs_vptofh(struct vnode *vp, struct fid *fhp)
  564: {
  565: 	struct hpfsnode *hpp;
  566: 	struct hpfid *hpfhp;
  567: 
  568: 	hpp = VTOHP(vp);
  569: 	hpfhp = (struct hpfid *)fhp;
  570: 	hpfhp->hpfid_len = sizeof(struct hpfid);
  571: 	hpfhp->hpfid_ino = hpp->h_no;
  572: 	/* hpfhp->hpfid_gen = hpp->h_gen; */
  573: 	return (0);
  574: }
  575: 
  576: static int
  577: hpfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 
  578: {
  579: 	struct hpfsmount *hpmp = VFSTOHPFS(mp);
  580: 	struct vnode *vp;
  581: 	struct hpfsnode *hp;
  582: 	struct buf *bp;
  583: 	struct thread *td = curthread;	/* XXX */
  584: 	int error;
  585: 
  586: 	dprintf(("hpfs_vget(0x%x): ",ino));
  587: 
  588: 	*vpp = NULL;
  589: 	hp = NULL;
  590: 	vp = NULL;
  591: 
  592: 	if ((*vpp = hpfs_hphashvget(hpmp->hpm_dev, ino, td)) != NULL) {
  593: 		dprintf(("hashed\n"));
  594: 		return (0);
  595: 	}
  596: 
  597: 	/*
  598: 	 * We have to lock node creation for a while,
  599: 	 * but then we have to call getnewvnode(), 
  600: 	 * this may cause hpfs_reclaim() to be called,
  601: 	 * this may need to VOP_VGET() parent dir for
  602: 	 * update reasons, and if parent is not in
  603: 	 * hash, we have to lock node creation...
  604: 	 * To solve this, we MALLOC, getnewvnode and init while
  605: 	 * not locked (probability of node appearence
  606: 	 * at that time is little, and anyway - we'll
  607: 	 * check for it).
  608: 	 */
  609: 	MALLOC(hp, struct hpfsnode *, sizeof(struct hpfsnode), 
  610: 		M_HPFSNO, M_WAITOK);
  611: 
  612: 	error = getnewvnode(VT_HPFS, hpmp->hpm_mp, hpfs_vnodeop_p, &vp);
  613: 	if (error) {
  614: 		printf("hpfs_vget: can't get new vnode\n");
  615: 		FREE(hp, M_HPFSNO);
  616: 		return (error);
  617: 	}
  618: 
  619: 	dprintf(("prenew "));
  620: 
  621: 	vp->v_data = hp;
  622: 
  623: 	if (ino == (ino_t)hpmp->hpm_su.su_rootfno) 
  624: 		vp->v_flag |= VROOT;
  625: 
  626: 	lwkt_token_init(&hp->h_interlock);
  627: 	lockinit(&hp->h_lock, 0, "hpnode", VLKTIMEOUT, 0);
  628: 
  629: 	hp->h_flag = H_INVAL;
  630: 	hp->h_vp = vp;
  631: 	hp->h_hpmp = hpmp;
  632: 	hp->h_no = ino;
  633: 	hp->h_dev = hpmp->hpm_dev;
  634: 	hp->h_uid = hpmp->hpm_uid;
  635: 	hp->h_gid = hpmp->hpm_uid;
  636: 	hp->h_mode = hpmp->hpm_mode;
  637: 	hp->h_devvp = hpmp->hpm_devvp;
  638: 	vref(hp->h_devvp);
  639: 
  640: 	error = VN_LOCK(vp, LK_EXCLUSIVE, td);
  641: 	if (error) {
  642: 		vput(vp);
  643: 		return (error);
  644: 	}
  645: 
  646: 	do {
  647: 		if ((*vpp = hpfs_hphashvget(hpmp->hpm_dev, ino, td)) != NULL) {
  648: 			dprintf(("hashed2\n"));
  649: 			vput(vp);
  650: 			return (0);
  651: 		}
  652: 	} while(LOCKMGR(&hpfs_hphash_lock,LK_EXCLUSIVE|LK_SLEEPFAIL,NULL,NULL));
  653: 
  654: 	hpfs_hphashins(hp);
  655: 
  656: 	LOCKMGR(&hpfs_hphash_lock, LK_RELEASE, NULL, NULL);
  657: 
  658: 	error = bread(hpmp->hpm_devvp, ino, FNODESIZE, &bp);
  659: 	if (error) {
  660: 		printf("hpfs_vget: can't read ino %d\n",ino);
  661: 		vput(vp);
  662: 		return (error);
  663: 	}
  664: 	bcopy(bp->b_data, &hp->h_fn, sizeof(struct fnode));
  665: 	brelse(bp);
  666: 
  667: 	if (hp->h_fn.fn_magic != FN_MAGIC) {
  668: 		printf("hpfs_vget: MAGIC DOESN'T MATCH\n");
  669: 		vput(vp);
  670: 		return (EINVAL);
  671: 	}
  672: 
  673: 	vp->v_type = hp->h_fn.fn_flag ? VDIR:VREG;
  674: 	hp->h_flag &= ~H_INVAL;
  675: 
  676: 	*vpp = vp;
  677: 
  678: 	return (0);
  679: }
  680: 
  681: #if defined(__DragonFly__)
  682: static struct vfsops hpfs_vfsops = {
  683: 	hpfs_mount,
  684: 	vfs_stdstart,
  685: 	hpfs_unmount,
  686: 	hpfs_root,
  687: 	vfs_stdquotactl,
  688: 	hpfs_statfs,
  689: 	vfs_stdsync,
  690: 	hpfs_vget,
  691: 	hpfs_fhtovp,
  692: 	hpfs_checkexp,
  693: 	hpfs_vptofh,
  694: 	hpfs_init,
  695: 	hpfs_hphash_uninit,
  696: 	vfs_stdextattrctl,
  697: };
  698: VFS_SET(hpfs_vfsops, hpfs, 0);
  699: #else /* defined(__NetBSD__) */
  700: extern struct vnodeopv_desc hpfs_vnodeop_opv_desc;
  701: 
  702: struct vnodeopv_desc *hpfs_vnodeopv_descs[] = {
  703: 	&hpfs_vnodeop_opv_desc,
  704: 	NULL,
  705: };
  706: 
  707: struct vfsops hpfs_vfsops = {
  708: 	MOUNT_HPFS,
  709: 	hpfs_mount,
  710: 	hpfs_start,
  711: 	hpfs_unmount,
  712: 	hpfs_root,
  713: 	hpfs_quotactl,
  714: 	hpfs_statfs,
  715: 	hpfs_sync,
  716: 	hpfs_vget,
  717: 	hpfs_fhtovp,
  718: 	hpfs_vptofh,
  719: 	hpfs_init,
  720: 	hpfs_sysctl,
  721: 	hpfs_mountroot,
  722: 	hpfs_checkexp,
  723: 	hpfs_vnodeopv_descs,
  724: };
  725: #endif