genfs_node_init(nvp, &msdosfs_genfsops);
deget(pmp, dirclust, diroffset, depp)	struct msdosfsmount *pmp;	/* so we know the maj/min number */	u_long dirclust;		/* cluster this dir entry came from */	u_long diroffset;		/* index of entry within the cluster */	struct denode **depp;		/* returns the addr of the gotten denode */{	int error;	extern int (**msdosfs_vnodeop_p) __P((void *));	struct direntry *direntptr;	struct denode *ldep;	struct vnode *nvp;	struct buf *bp;	struct proc *p = curproc; /* XXX */#ifdef MSDOSFS_DEBUG	printf("deget(pmp %08x, dirclust %d, diroffset %x, depp %08x)\n",	    pmp, dirclust, diroffset, depp);#endif	/*	 * On FAT32 filesystems, root is a (more or less) normal	 * directory	 */	if (FAT32(pmp) && dirclust == MSDOSFSROOT)		dirclust = pmp->pm_rootdirblk;	/*	 * See if the denode is in the denode cache. Use the location of	 * the directory entry to compute the hash value. For subdir use	 * address of "." entry. For root dir (if not FAT32) use cluster	 * MSDOSFSROOT, offset MSDOSFSROOT_OFS	 * 	 * NOTE: The check for de_refcnt > 0 below insures the denode being	 * examined does not represent an unlinked but still open file.	 * These files are not to be accessible even when the directory	 * entry that represented the file happens to be reused while the	 * deleted file is still open.	 */retry:	ldep = msdosfs_hashget(pmp->pm_dev, dirclust, diroffset);	if (ldep) {		*depp = ldep;		return (0);	}	/*	 * Directory entry was not in cache, have to create a vnode and	 * copy it from the passed disk buffer.	 */	/* getnewvnode() does a VREF() on the vnode */	error = getnewvnode(VT_MSDOSFS, pmp->pm_mountp,			    msdosfs_vnodeop_p, &nvp);	if (error) {		*depp = 0;		return (error);	}	MALLOC(ldep, struct denode *, sizeof(struct denode), M_MSDOSFSNODE,	    M_WAITOK);	bzero((caddr_t)ldep, sizeof *ldep);	lockinit(&ldep->de_lock, PINOD, "denode", 0, 0);	nvp->v_data = ldep;	ldep->de_vnode = nvp;	ldep->de_flag = 0;	ldep->de_devvp = 0;	ldep->de_lockf = 0;	ldep->de_dev = pmp->pm_dev;	ldep->de_dirclust = dirclust;	ldep->de_diroffset = diroffset;	fc_purge(ldep, 0);	/* init the fat cache for this denode */	/*	 * Insert the denode into the hash queue and lock the denode so it	 * can't be accessed until we've read it in and have done what we	 * need to it.	 */	vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY, p);	error = msdosfs_hashins(ldep);	if (error) {		vput (nvp);				if (error == EEXIST)			goto retry;		return (error);	}	ldep->de_pmp = pmp;	ldep->de_devvp = pmp->pm_devvp;	ldep->de_refcnt = 1;	/*	 * Copy the directory entry into the denode area of the vnode.	 */	if ((dirclust == MSDOSFSROOT	     || (FAT32(pmp) && dirclust == pmp->pm_rootdirblk))	    && diroffset == MSDOSFSROOT_OFS) {		/*		 * Directory entry for the root directory. There isn't one,		 * so we manufacture one. We should probably rummage		 * through the root directory and find a label entry (if it		 * exists), and then use the time and date from that entry		 * as the time and date for the root denode.		 */	        nvp->v_flag |= VROOT; /* should be further down         XXX */		ldep->de_Attributes = ATTR_DIRECTORY;		if (FAT32(pmp))		        ldep->de_StartCluster = pmp->pm_rootdirblk;		        /* de_FileSize will be filled in further down */		else {		        ldep->de_StartCluster = MSDOSFSROOT;		        ldep->de_FileSize = pmp->pm_rootdirsize * pmp->pm_BytesPerSec;		}		/*		 * fill in time and date so that dos2unixtime() doesn't		 * spit up when called from msdosfs_getattr() with root		 * denode		 */		ldep->de_CTime = 0x0000;	/* 00:00:00	 */		ldep->de_CTimeHundredth = 0;		ldep->de_CDate = (0 << DD_YEAR_SHIFT) | (1 << DD_MONTH_SHIFT)		    | (1 << DD_DAY_SHIFT);		/* Jan 1, 1980	 */		ldep->de_ADate = ldep->de_CDate;		ldep->de_MTime = ldep->de_CTime;		ldep->de_MDate = ldep->de_CDate;		/* leave the other fields as garbage */	} else {		error = readep(pmp, dirclust, diroffset, &bp, &direntptr);		if (error)			return (error);		DE_INTERNALIZE(ldep, direntptr);		brelse(bp);	}	/*	 * Fill in a few fields of the vnode and finish filling in the	 * denode.  Then return the address of the found denode.	 */	if (ldep->de_Attributes & ATTR_DIRECTORY) {		/*		 * Since DOS directory entries that describe directories		 * have 0 in the filesize field, we take this opportunity		 * to find out the length of the directory and plug it into		 * the denode structure.		 */		u_long size;		nvp->v_type = VDIR;		if (ldep->de_StartCluster != MSDOSFSROOT) {			error = pcbmap(ldep, 0xffff, 0, &size, 0);			if (error == E2BIG) {				ldep->de_FileSize = de_cn2off(pmp, size);				error = 0;			} else				printf("deget(): pcbmap returned %d\n", error);		}	} else		nvp->v_type = VREG;	genfs_node_init(nvp, &msdosfs_genfsops);	VREF(ldep->de_devvp);	*depp = ldep;	nvp->v_size = ldep->de_FileSize;	return (0);}