+ }
+ /*
+ * 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 ((mp->mnt_flag & MNT_UPDATE) == 0)
+ error = ffs_mountfs(devvp, mp, p);
+ else {
+ if (devvp != ump->um_devvp)
+ error = EINVAL; /* needs translation */
+ else
+ vrele(devvp);
+ }
+ if (error) {
+ vrele(devvp);
+ return (error);
+ }
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
+ bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
+ bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
+ MNAMELEN);
+ (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
+ &size);
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void)ffs_statfs(mp, &mp->mnt_stat, p);
+ return (0);
+}
+
+/*
+ * Common code for mount and mountroot
+ */
+int
+ffs_mountfs(devvp, mp, p)
+ register struct vnode *devvp;
+ struct mount *mp;
+ struct proc *p;
+{
+ register struct ufsmount *ump;
+ struct buf *bp;
+ register struct fs *fs;
+ dev_t dev = devvp->v_rdev;
+ struct partinfo dpart;
+ int havepart = 0, blks;
+ caddr_t base, space;
+ int havepart = 0, blks;
+ int error, i, size;
+ int ronly;
+ extern struct vnode *rootvp;
+
+ if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
+ return (error);
+ if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
+ size = DEV_BSIZE;
+ else {
+ havepart = 1;
+ size = dpart.disklab->d_secsize;
+ }
+
+ bp = NULL;
+ ump = NULL;
+ if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp))
+ goto out;
+ fs = bp->b_un.b_fs;
+ error = EINVAL; /* XXX needs translation */