FreeBSD/sys/fs/ext2fs/ext2_vfsops.c
/*
 * Reload all incore data for a filesystem (used after running fsck on
 * the root filesystem and finding things to fix). The filesystem must
 * be mounted read-only.
 *
 * Things to do to update the mount:
 *	1) invalidate all cached meta-data.
 *	2) re-read superblock from disk.
 *	3) invalidate all cluster summary information.
 *	4) invalidate all inactive vnodes.
 *	5) invalidate all cached file data.
 *	6) re-read inode data for all active vnodes.
 * XXX we are missing some steps, in particular # 3, this has to be reviewed.
 */
Reload all incore data for a filesystem (used after running fsck on
the root filesystem and finding things to fix). The filesystem must
be mounted read-only.

Things to do to update the mount:
1) invalidate all cached meta-data.
2) re-read superblock from disk.
3) invalidate all cluster summary information.
4) invalidate all inactive vnodes.
5) invalidate all cached file data.
6) re-read inode data for all active vnodes.
XXX we are missing some steps, in particular # 3, this has to be reviewed.
Reload all incore data for a filesystem ( used after running fsck on the root filesystem and finding things to fix ) . The filesystem must be mounted read - only . Things to do to update the mount : 1 ) invalidate all cached meta - data . 2 ) re - read superblock from disk . 3 ) invalidate all cluster summary information . 4 ) invalidate all inactive vnodes . 5 ) invalidate all cached file data . 6 ) re - read inode data for all active vnodes . XXX we are missing some steps in particular # 3 this has to be reviewed .
static int
ext2_reload(struct mount *mp, struct thread *td)
{
	struct vnode *vp, *mvp, *devvp;
	struct inode *ip;
	struct buf *bp;
	struct ext2fs *es;
	struct m_ext2fs *fs;
	struct csum *sump;
	int error, i;
	int32_t *lp;
	if ((mp->mnt_flag & MNT_RDONLY) == 0)
		return (EINVAL);
	devvp = VFSTOEXT2(mp)->um_devvp;
	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
	if (vinvalbuf(devvp, 0, 0, 0) != 0)
		panic("ext2_reload: dirty1");
	VOP_UNLOCK(devvp, 0);
	if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0)
		return (error);
	es = (struct ext2fs *)bp->b_data;
	if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) {
		brelse(bp);
		return (EIO);		
	}
	fs = VFSTOEXT2(mp)->um_e2fs;
	bcopy(bp->b_data, fs->e2fs, sizeof(struct ext2fs));
	if((error = compute_sb_data(devvp, es, fs)) != 0) {
		brelse(bp);
		return (error);
	}
#ifdef UNKLAR
	if (fs->fs_sbsize < SBSIZE)
		bp->b_flags |= B_INVAL;
#endif
	brelse(bp);
	if (fs->e2fs_contigsumsize > 0) {
		lp = fs->e2fs_maxcluster;
		sump = fs->e2fs_clustersum;
		for (i = 0; i < fs->e2fs_gcount; i++, sump++) {
			*lp++ = fs->e2fs_contigsumsize;
			sump->cs_init = 0;
			bzero(sump->cs_sum, fs->e2fs_contigsumsize + 1);
		}
	}
loop:
	MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
			goto loop;
		}
		if (vinvalbuf(vp, 0, 0, 0))
			panic("ext2_reload: dirty2");
		ip = VTOI(vp);
		error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
		    (int)fs->e2fs_bsize, NOCRED, &bp);
		if (error) {
			VOP_UNLOCK(vp, 0);
			vrele(vp);
			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
			return (error);
		}
		ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data +
		    EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)), ip);
		brelse(bp);
		VOP_UNLOCK(vp, 0);
		vrele(vp);
	}
	return (0);
}
static int ext2_reload ( struct mount * mp , struct thread * td ) { struct vnode * vp , * mvp , * devvp ; struct inode * ip ; struct buf * bp ; struct ext2fs * es ; struct m_ext2fs * fs ; struct csum * sump ; int error , i ; int32_t * lp ; if ( ( mp -> mnt_flag & MNT_RDONLY ) == 0 ) return ( EINVAL ) ; devvp = VFSTOEXT2 ( mp ) -> um_devvp ; vn_lock ( devvp , LK_EXCLUSIVE | LK_RETRY ) ; if ( vinvalbuf ( devvp , 0 , 0 , 0 ) != 0 ) panic ( " " ) ; VOP_UNLOCK ( devvp , 0 ) ; if ( ( error = bread ( devvp , SBLOCK , SBSIZE , NOCRED , & bp ) ) != 0 ) return ( error ) ; es = ( struct ext2fs * ) bp -> b_data ; if ( ext2_check_sb_compat ( es , devvp -> v_rdev , 0 ) != 0 ) { brelse ( bp ) ; return ( EIO ) ; } fs = VFSTOEXT2 ( mp ) -> um_e2fs ; bcopy ( bp -> b_data , fs -> e2fs , sizeof ( struct ext2fs ) ) ; if ( ( error = compute_sb_data ( devvp , es , fs ) ) != 0 ) { brelse ( bp ) ; return ( error ) ; } #ifdef UNKLAR if ( fs -> fs_sbsize < SBSIZE ) bp -> b_flags |= B_INVAL ; #endif brelse ( bp ) ; if ( fs -> e2fs_contigsumsize > 0 ) { lp = fs -> e2fs_maxcluster ; sump = fs -> e2fs_clustersum ; for ( i = 0 ; i < fs -> e2fs_gcount ; i ++ , sump ++ ) { * lp ++ = fs -> e2fs_contigsumsize ; sump -> cs_init = 0 ; bzero ( sump -> cs_sum , fs -> e2fs_contigsumsize + 1 ) ; } } loop : MNT_VNODE_FOREACH_ALL ( vp , mp , mvp ) { if ( vget ( vp , LK_EXCLUSIVE | LK_INTERLOCK , td ) ) { MNT_VNODE_FOREACH_ALL_ABORT ( mp , mvp ) ; goto loop ; } if ( vinvalbuf ( vp , 0 , 0 , 0 ) ) panic ( " " ) ; ip = VTOI ( vp ) ; error = bread ( devvp , fsbtodb ( fs , ino_to_fsba ( fs , ip -> i_number ) ) , ( int ) fs -> e2fs_bsize , NOCRED , & bp ) ; if ( error ) { VOP_UNLOCK ( vp , 0 ) ; vrele ( vp ) ; MNT_VNODE_FOREACH_ALL_ABORT ( mp , mvp ) ; return ( error ) ; } ext2_ei2i ( ( struct ext2fs_dinode * ) ( ( char * ) bp -> b_data + EXT2_INODE_SIZE ( fs ) * ino_to_fsbo ( fs , ip -> i_number ) ) , ip ) ; brelse ( bp ) ; VOP_UNLOCK ( vp , 0 ) ; vrele ( vp ) ; } return ( 0 ) ; }
Reload all incore data for a filesystem (used after running fsck on
 the root filesystem and finding things to fix).
Reload all incore data for a filesystem ( used after running fsck on the root filesystem and finding things to fix ) .
/*
	 * Step 1: invalidate all cached meta-data.
	 */ /*
	 * Step 2: re-read superblock from disk.
	 * constants have been adjusted for ext2
	 */ /* XXX needs translation */ /*
	 * Step 3: invalidate all cluster summary information.
	 */ /*
		 * Step 4: invalidate all cached file data.
		 */ /*
		 * Step 5: re-read inode data for all active vnodes.
		 */