FreeBSD/sys/ufs/ffs/ffs_vfsops.c
/*
 * Reload all incore data for a filesystem (used after running fsck on
 * the root filesystem and finding things to fix). If the 'force' flag
 * is 0, 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) re-read summary information from disk.
 *	4) invalidate all inactive vnodes.
 *	5) invalidate all cached file data.
 *	6) re-read inode data for all active vnodes.
 */
Reload all incore data for a filesystem (used after running fsck on
the root filesystem and finding things to fix). If the 'force' flag
is 0, 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) re-read summary information from disk.
4) invalidate all inactive vnodes.
5) invalidate all cached file data.
6) re-read inode data for all active vnodes.
Reload all incore data for a filesystem ( used after running fsck on the root filesystem and finding things to fix ) . If the ' force ' flag is 0 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 ) re - read summary information from disk . 4 ) invalidate all inactive vnodes . 5 ) invalidate all cached file data . 6 ) re - read inode data for all active vnodes .
int
ffs_reload(struct mount *mp, struct thread *td, int force)
{
	struct vnode *vp, *mvp, *devvp;
	struct inode *ip;
	void *space;
	struct buf *bp;
	struct fs *fs, *newfs;
	struct ufsmount *ump;
	ufs2_daddr_t sblockloc;
	int i, blks, size, error;
	int32_t *lp;
	ump = VFSTOUFS(mp);
	MNT_ILOCK(mp);
	if ((mp->mnt_flag & MNT_RDONLY) == 0 && force == 0) {
		MNT_IUNLOCK(mp);
		return (EINVAL);
	}
	MNT_IUNLOCK(mp);
	devvp = VFSTOUFS(mp)->um_devvp;
	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
	if (vinvalbuf(devvp, 0, 0, 0) != 0)
		panic("ffs_reload: dirty1");
	VOP_UNLOCK(devvp, 0);
	fs = VFSTOUFS(mp)->um_fs;
	if ((error = bread(devvp, btodb(fs->fs_sblockloc), fs->fs_sbsize,
	    NOCRED, &bp)) != 0)
		return (error);
	newfs = (struct fs *)bp->b_data;
	if ((newfs->fs_magic != FS_UFS1_MAGIC &&
	     newfs->fs_magic != FS_UFS2_MAGIC) ||
	    newfs->fs_bsize > MAXBSIZE ||
	    newfs->fs_bsize < sizeof(struct fs)) {
			brelse(bp);
			return (EIO);		
	}
	newfs->fs_csp = fs->fs_csp;
	newfs->fs_maxcluster = fs->fs_maxcluster;
	newfs->fs_contigdirs = fs->fs_contigdirs;
	newfs->fs_active = fs->fs_active;
	newfs->fs_ronly = fs->fs_ronly;
	sblockloc = fs->fs_sblockloc;
	bcopy(newfs, fs, (u_int)fs->fs_sbsize);
	brelse(bp);
	mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
	ffs_oldfscompat_read(fs, VFSTOUFS(mp), sblockloc);
	UFS_LOCK(ump);
	if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
		printf("WARNING: %s: reload pending error: blocks %jd "
		    "files %d\n", fs->fs_fsmnt, (intmax_t)fs->fs_pendingblocks,
		    fs->fs_pendinginodes);
		fs->fs_pendingblocks = 0;
		fs->fs_pendinginodes = 0;
	}
	UFS_UNLOCK(ump);
	size = fs->fs_cssize;
	blks = howmany(size, fs->fs_fsize);
	if (fs->fs_contigsumsize > 0)
		size += fs->fs_ncg * sizeof(int32_t);
	size += fs->fs_ncg * sizeof(u_int8_t);
	free(fs->fs_csp, M_UFSMNT);
	space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
	fs->fs_csp = space;
	for (i = 0; i < blks; i += fs->fs_frag) {
		size = fs->fs_bsize;
		if (i + fs->fs_frag > blks)
			size = (blks - i) * fs->fs_fsize;
		error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
		    NOCRED, &bp);
		if (error)
			return (error);
		bcopy(bp->b_data, space, (u_int)size);
		space = (char *)space + size;
		brelse(bp);
	}
	if (fs->fs_contigsumsize > 0) {
		fs->fs_maxcluster = lp = space;
		for (i = 0; i < fs->fs_ncg; i++)
			*lp++ = fs->fs_contigsumsize;
		space = lp;
	}
	size = fs->fs_ncg * sizeof(u_int8_t);
	fs->fs_contigdirs = (u_int8_t *)space;
	bzero(fs->fs_contigdirs, size);
loop:
	MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
		if (vp->v_type == VNON) {
			VI_UNLOCK(vp);
			continue;
		}
		if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
			goto loop;
		}
		if (vinvalbuf(vp, 0, 0, 0))
			panic("ffs_reload: dirty2");
		ip = VTOI(vp);
		error =
		    bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
		    (int)fs->fs_bsize, NOCRED, &bp);
		if (error) {
			VOP_UNLOCK(vp, 0);
			vrele(vp);
			MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
			return (error);
		}
		ffs_load_inode(bp, ip, fs, ip->i_number);
		ip->i_effnlink = ip->i_nlink;
		brelse(bp);
		VOP_UNLOCK(vp, 0);
		vrele(vp);
	}
	return (0);
}
int ffs_reload ( struct mount * mp , struct thread * td , int force ) { struct vnode * vp , * mvp , * devvp ; struct inode * ip ; void * space ; struct buf * bp ; struct fs * fs , * newfs ; struct ufsmount * ump ; ufs2_daddr_t sblockloc ; int i , blks , size , error ; int32_t * lp ; ump = VFSTOUFS ( mp ) ; MNT_ILOCK ( mp ) ; if ( ( mp -> mnt_flag & MNT_RDONLY ) == 0 && force == 0 ) { MNT_IUNLOCK ( mp ) ; return ( EINVAL ) ; } MNT_IUNLOCK ( mp ) ; devvp = VFSTOUFS ( mp ) -> um_devvp ; vn_lock ( devvp , LK_EXCLUSIVE | LK_RETRY ) ; if ( vinvalbuf ( devvp , 0 , 0 , 0 ) != 0 ) panic ( " " ) ; VOP_UNLOCK ( devvp , 0 ) ; fs = VFSTOUFS ( mp ) -> um_fs ; if ( ( error = bread ( devvp , btodb ( fs -> fs_sblockloc ) , fs -> fs_sbsize , NOCRED , & bp ) ) != 0 ) return ( error ) ; newfs = ( struct fs * ) bp -> b_data ; if ( ( newfs -> fs_magic != FS_UFS1_MAGIC && newfs -> fs_magic != FS_UFS2_MAGIC ) || newfs -> fs_bsize > MAXBSIZE || newfs -> fs_bsize < sizeof ( struct fs ) ) { brelse ( bp ) ; return ( EIO ) ; } newfs -> fs_csp = fs -> fs_csp ; newfs -> fs_maxcluster = fs -> fs_maxcluster ; newfs -> fs_contigdirs = fs -> fs_contigdirs ; newfs -> fs_active = fs -> fs_active ; newfs -> fs_ronly = fs -> fs_ronly ; sblockloc = fs -> fs_sblockloc ; bcopy ( newfs , fs , ( u_int ) fs -> fs_sbsize ) ; brelse ( bp ) ; mp -> mnt_maxsymlinklen = fs -> fs_maxsymlinklen ; ffs_oldfscompat_read ( fs , VFSTOUFS ( mp ) , sblockloc ) ; UFS_LOCK ( ump ) ; if ( fs -> fs_pendingblocks != 0 || fs -> fs_pendinginodes != 0 ) { printf ( " " " \n " , fs -> fs_fsmnt , ( intmax_t ) fs -> fs_pendingblocks , fs -> fs_pendinginodes ) ; fs -> fs_pendingblocks = 0 ; fs -> fs_pendinginodes = 0 ; } UFS_UNLOCK ( ump ) ; size = fs -> fs_cssize ; blks = howmany ( size , fs -> fs_fsize ) ; if ( fs -> fs_contigsumsize > 0 ) size += fs -> fs_ncg * sizeof ( int32_t ) ; size += fs -> fs_ncg * sizeof ( u_int8_t ) ; free ( fs -> fs_csp , M_UFSMNT ) ; space = malloc ( ( u_long ) size , M_UFSMNT , M_WAITOK ) ; fs -> fs_csp = space ; for ( i = 0 ; i < blks ; i += fs -> fs_frag ) { size = fs -> fs_bsize ; if ( i + fs -> fs_frag > blks ) size = ( blks - i ) * fs -> fs_fsize ; error = bread ( devvp , fsbtodb ( fs , fs -> fs_csaddr + i ) , size , NOCRED , & bp ) ; if ( error ) return ( error ) ; bcopy ( bp -> b_data , space , ( u_int ) size ) ; space = ( char * ) space + size ; brelse ( bp ) ; } if ( fs -> fs_contigsumsize > 0 ) { fs -> fs_maxcluster = lp = space ; for ( i = 0 ; i < fs -> fs_ncg ; i ++ ) * lp ++ = fs -> fs_contigsumsize ; space = lp ; } size = fs -> fs_ncg * sizeof ( u_int8_t ) ; fs -> fs_contigdirs = ( u_int8_t * ) space ; bzero ( fs -> fs_contigdirs , size ) ; loop : MNT_VNODE_FOREACH_ALL ( vp , mp , mvp ) { if ( vp -> v_type == VNON ) { VI_UNLOCK ( vp ) ; continue ; } 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 -> fs_bsize , NOCRED , & bp ) ; if ( error ) { VOP_UNLOCK ( vp , 0 ) ; vrele ( vp ) ; MNT_VNODE_FOREACH_ALL_ABORT ( mp , mvp ) ; return ( error ) ; } ffs_load_inode ( bp , ip , fs , ip -> i_number ) ; ip -> i_effnlink = ip -> i_nlink ; 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.
	 */ /* XXX needs translation */ /*
	 * Copy pointer fields back into superblock before copying in	XXX
	 * new superblock. These should really be in the ufsmount.	XXX
	 * Note that important parameters (eg fs_ncg) are unchanged.
	 */ /*
	 * Step 3: re-read summary information from disk.
	 */ /*
	 * We no longer know anything about clusters per cylinder group.
	 */ /*
		 * Skip syncer vnode.
		 */ /*
		 * Step 4: invalidate all cached file data.
		 */ /*
		 * Step 5: re-read inode data for all active vnodes.
		 */