- (void)iflush(dev, (struct inode *)NULL);
-#endif
- ip = mp->m_inodp;
- ip->i_flag &= ~IMOUNT;
- fs = mp->m_fs;
- free((caddr_t)fs->fs_csp[0], M_SUPERBLK);
- free((caddr_t)mp->m_fs, M_SUPERBLK);
- mp->m_fs = NULL;
- mp->m_dev = NODEV;
- mpurge(mp - &mount[0]);
- error = closei(dev, IFBLK, fs->fs_ronly? FREAD : FREAD|FWRITE);
- irele(ip);
- return (error);
+ ufs_ihashins(ip);
+
+ /* Read in the disk contents for the inode, copy into the inode. */
+ if (error = bread(ump->um_devvp, fsbtodb(fs, itod(fs, ino)),
+ (int)fs->fs_bsize, NOCRED, &bp)) {
+ /*
+ * The inode does not contain anything useful, so it would
+ * be misleading to leave it on its hash chain. It will be
+ * returned to the free list by ufs_iput().
+ */
+ ufs_ihashrem(ip);
+
+ /* Unlock and discard unneeded inode. */
+ ufs_iput(ip);
+ brelse(bp);
+ *vpp = NULL;
+ return (error);
+ }
+ dp = bp->b_un.b_dino;
+ dp += itoo(fs, ino);
+ ip->i_din = *dp;
+ brelse(bp);
+
+ /*
+ * Initialize the vnode from the inode, check for aliases.
+ * Note that the underlying vnode may have changed.
+ */
+ if (error = ufs_vinit(mp, ffs_specop_p, FFS_FIFOOPS, &vp)) {
+ ufs_iput(ip);
+ *vpp = NULL;
+ return (error);
+ }
+ /*
+ * Finish inode initialization now that aliasing has been resolved.
+ */
+ ip->i_devvp = ump->um_devvp;
+ VREF(ip->i_devvp);
+ /*
+ * Set up a generation number for this inode if it does not
+ * already have one. This should only happen on old filesystems.
+ */
+ if (ip->i_gen == 0) {
+ if (++nextgennumber < (u_long)time.tv_sec)
+ nextgennumber = time.tv_sec;
+ ip->i_gen = nextgennumber;
+ if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
+ ip->i_flag |= IMOD;
+ }
+ /*
+ * Ensure that uid and gid are correct. This is a temporary
+ * fix until fsck has been changed to do the update.
+ */
+ if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
+ ip->i_uid = ip->i_din.di_ouid; /* XXX */
+ ip->i_gid = ip->i_din.di_ogid; /* XXX */
+ } /* XXX */
+
+ *vpp = vp;
+ return (0);