+ if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
+ return (error);
+ /*
+ * Process export requests.
+ */
+ if ((args.exflags & MNT_EXPORTED) || (mp->mnt_flag & MNT_EXPORTED)) {
+ if (args.exflags & MNT_EXPORTED)
+ mp->mnt_flag |= MNT_EXPORTED;
+ else
+ mp->mnt_flag &= ~MNT_EXPORTED;
+ if (args.exflags & MNT_EXRDONLY)
+ mp->mnt_flag |= MNT_EXRDONLY;
+ else
+ mp->mnt_flag &= ~MNT_EXRDONLY;
+ mp->mnt_exroot = args.exroot;
+ }
+ if ((mp->mnt_flag & MNT_UPDATE) == 0) {
+ if ((error = getmdev(&devvp, args.fspec, ndp)) != 0)
+ return (error);
+ error = mountfs(devvp, mp);
+ } else {
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
+ fs->fs_ronly = 0;
+ /*
+ * Verify that the specified device is the one that
+ * is really being used for the root file system.
+ */
+ if (args.fspec == 0)
+ return (0);
+ if ((error = getmdev(&devvp, args.fspec, ndp)) != 0)
+ return (error);
+ 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) ufs_statfs(mp, &mp->mnt_stat);
+ return (0);
+}
+
+/*
+ * Common code for mount and mountroot
+ */
+mountfs(devvp, mp)
+ register struct vnode *devvp;
+ struct mount *mp;
+{
+ register struct ufsmount *ump = (struct ufsmount *)0;
+ struct buf *bp = NULL;
+ 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 needclose = 0;
+ int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
+
+ if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED))
+ return (error);
+ needclose = 1;
+ if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED) != 0) {
+ size = DEV_BSIZE;
+ } else {
+ havepart = 1;
+ size = dpart.disklab->d_secsize;
+ }
+ if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp))