+ if (error = vfs_lock(mp)) {
+ (void)ufs_unmount(mp, 0);
+ free((caddr_t)mp, M_MOUNT);
+ return (error);
+ }
+ rootfs = mp;
+ mp->mnt_next = mp;
+ mp->mnt_prev = mp;
+ mp->mnt_vnodecovered = NULLVP;
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
+ fs->fs_fsmnt[0] = '/';
+ bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
+ MNAMELEN);
+ (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
+ &size);
+ bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ (void) ufs_statfs(mp, &mp->mnt_stat);
+ vfs_unlock(mp);
+ inittodr(fs->fs_time);
+ return (0);
+}
+
+/*
+ * VFS Operations.
+ *
+ * mount system call
+ */
+ufs_mount(mp, path, data, ndp)
+ register struct mount *mp;
+ char *path;
+ caddr_t data;
+ struct nameidata *ndp;
+{
+ struct vnode *devvp;
+ struct ufs_args args;
+ struct ufsmount *ump;
+ register struct fs *fs;
+ u_int size;
+ int error;
+
+ 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);