if (pmp->pm_flags & MSDOSFSMNT_GEMDOSFS) pmp->pm_flags |= MSDOSFSMNT_NOWIN95;
msdosfs_mount(mp, path, data, ndp, p)	struct mount *mp;	char *path;	caddr_t data;	struct nameidata *ndp;	struct proc *p;{	struct vnode *devvp;	  /* vnode for blk device to mount */	struct msdosfs_args args; /* will hold data from mount request */	struct msdosfsmount *pmp; /* msdosfs specific mount control block */	size_t size;	int error, flags;	mode_t accessmode;	if (error = copyin(data, (caddr_t)&args, sizeof(struct msdosfs_args)))		return (error);	/*	 * If updating, check whether changing from read-only to	 * read/write; if there is no device name, that's all we do.	 */	if (mp->mnt_flag & MNT_UPDATE) {		pmp = VFSTOMSDOSFS(mp);		error = 0;		if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_RDONLY)) {			flags = WRITECLOSE;			if (mp->mnt_flag & MNT_FORCE)				flags |= FORCECLOSE;			if (vfs_busy(mp))				return (EBUSY);			error = vflush(mp, NULLVP, flags);			vfs_unbusy(mp);		}		if (!error && (mp->mnt_flag & MNT_RELOAD))			/* not yet implemented */			error = EOPNOTSUPP;		if (error)			return (error);		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_WANTRDWR)) {			/*			 * If upgrade to read-write by non-root, then verify			 * that user has necessary permissions on the device.			 */			if (p->p_ucred->cr_uid != 0) {				devvp = pmp->pm_devvp;				VOP_LOCK(devvp);				if (error = VOP_ACCESS(devvp, VREAD | VWRITE,				    p->p_ucred, p)) {					VOP_UNLOCK(devvp);					return (error);				}				VOP_UNLOCK(devvp);			}			pmp->pm_flags &= ~MSDOSFSMNT_RONLY;		}		if (args.fspec == 0) {#ifdef	__notyet__		/* doesn't work correctly with current mountd	XXX */			if (args.flags & MSDOSFSMNT_MNTOPT) {				pmp->pm_flags &= ~MSDOSFSMNT_MNTOPT;				pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;				if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)					pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;			}#endif			/*			 * Process export requests.			 */			return (vfs_export(mp, &pmp->pm_export, &args.export));		}	}	/*	 * Not an update, or updating the name: look up the name	 * and verify that it refers to a sensible block device.	 */	NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);	if (error = namei(ndp))		return (error);	devvp = ndp->ni_vp;	if (devvp->v_type != VBLK) {		vrele(devvp);		return (ENOTBLK);	}	if (major(devvp->v_rdev) >= nblkdev) {		vrele(devvp);		return (ENXIO);	}	/*	 * If mount by non-root, then verify that user has necessary	 * permissions on the device.	 */	if (p->p_ucred->cr_uid != 0) {		accessmode = VREAD;		if ((mp->mnt_flag & MNT_RDONLY) == 0)			accessmode |= VWRITE;		VOP_LOCK(devvp);		if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) {			vput(devvp);			return (error);		}		VOP_UNLOCK(devvp);	}	if ((mp->mnt_flag & MNT_UPDATE) == 0)		error = msdosfs_mountfs(devvp, mp, p);	else {		if (devvp != pmp->pm_devvp)			error = EINVAL;	/* needs translation */		else			vrele(devvp);	}	if (error) {		vrele(devvp);		return (error);	}	pmp = VFSTOMSDOSFS(mp);	pmp->pm_gid = args.gid;	pmp->pm_uid = args.uid;	pmp->pm_mask = args.mask;	pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;	if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)		pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;	else if (!(pmp->pm_flags & (MSDOSFSMNT_SHORTNAME | MSDOSFSMNT_LONGNAME))) {		struct vnode *rootvp;				/*		 * Try to divine whether to support Win'95 long filenames		 */		if (error = msdosfs_root(mp, &rootvp)) {			msdosfs_unmount(mp, MNT_FORCE, p);			return (error);		}		pmp->pm_flags |= findwin95(VTODE(rootvp))		    ? MSDOSFSMNT_LONGNAME		    : MSDOSFSMNT_SHORTNAME;		vput(rootvp);	}	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);	(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,	    &size);	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);#ifdef MSDOSFS_DEBUG	printf("msdosfs_mount(): mp %x, pmp %x, inusemap %x\n", mp, pmp, pmp->pm_inusemap);#endif	return (0);}