FreeBSD/sys/fs/ext2fs/ext2_vfsops.c
/*
 * This computes the fields of the m_ext2fs structure from the
 * data in the ext2fs structure read in.
 */
This computes the fields of the m_ext2fs structure from the
data in the ext2fs structure read in.
This computes the fields of the m_ext2fs structure from the data in the ext2fs structure read in .
static int
compute_sb_data(struct vnode *devvp, struct ext2fs *es,
    struct m_ext2fs *fs)
{
	int db_count, error;
	int i;
	int logic_sb_block = 1;	
	struct buf *bp;
	uint32_t e2fs_descpb;
	fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->e2fs_log_bsize;
	fs->e2fs_bsize = 1U << fs->e2fs_bshift;
	fs->e2fs_fsbtodb = es->e2fs_log_bsize + 1;
	fs->e2fs_qbmask = fs->e2fs_bsize - 1;
	fs->e2fs_fsize = EXT2_MIN_FRAG_SIZE << es->e2fs_log_fsize;
	if (fs->e2fs_fsize)
		fs->e2fs_fpb = fs->e2fs_bsize / fs->e2fs_fsize;
	fs->e2fs_bpg = es->e2fs_bpg;
	fs->e2fs_fpg = es->e2fs_fpg;
	fs->e2fs_ipg = es->e2fs_ipg;
	if (es->e2fs_rev == E2FS_REV0) {
		fs->e2fs_isize = E2FS_REV0_INODE_SIZE ;
	} else {
		fs->e2fs_isize = es->e2fs_inode_size;
		if (EXT2_INODE_SIZE(fs) < E2FS_REV0_INODE_SIZE ||
		    EXT2_INODE_SIZE(fs) > fs->e2fs_bsize ||
		    (fs->e2fs_isize & (fs->e2fs_isize - 1)) != 0) {
			printf("ext2fs: invalid inode size %d\n",
			    fs->e2fs_isize);
			return (EIO);
		}
	}
	if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_EXTRA_ISIZE) &&
	    EXT2_INODE_SIZE(fs) < sizeof(struct ext2fs_dinode)) {
		printf("ext2fs: no space for extra inode timestamps\n");
		return (EINVAL);
	}
	fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
	fs->e2fs_itpg = fs->e2fs_ipg / fs->e2fs_ipb;
	fs->e2fs_gcount = howmany(es->e2fs_bcount - es->e2fs_first_dblock,
	    EXT2_BLOCKS_PER_GROUP(fs));
	e2fs_descpb = fs->e2fs_bsize / sizeof(struct ext2_gd);
	db_count = howmany(fs->e2fs_gcount, e2fs_descpb);
	fs->e2fs_gdbcount = db_count;
	fs->e2fs_gd = malloc(db_count * fs->e2fs_bsize,
	    M_EXT2MNT, M_WAITOK);
	fs->e2fs_contigdirs = malloc(fs->e2fs_gcount *
	    sizeof(*fs->e2fs_contigdirs), M_EXT2MNT, M_WAITOK | M_ZERO);
	if(fs->e2fs_bsize > SBSIZE)
		logic_sb_block = 0;
	for (i = 0; i < db_count; i++) {
		error = bread(devvp ,
			 fsbtodb(fs, logic_sb_block + i + 1 ),
			fs->e2fs_bsize, NOCRED, &bp);
		if (error) {
			free(fs->e2fs_contigdirs, M_EXT2MNT);
			free(fs->e2fs_gd, M_EXT2MNT);
			brelse(bp);
			return (error);
		}
		e2fs_cgload((struct ext2_gd *)bp->b_data,
		    &fs->e2fs_gd[
			i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
		    fs->e2fs_bsize);
		brelse(bp);
		bp = NULL;
	}
	fs->e2fs_total_dir = 0;
	for (i = 0; i < fs->e2fs_gcount; i++)
		fs->e2fs_total_dir += fs->e2fs_gd[i].ext2bgd_ndirs;
	if (es->e2fs_rev == E2FS_REV0 ||
	    !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_LARGEFILE))
		fs->e2fs_maxfilesize = 0x7fffffff;
	else {
		fs->e2fs_maxfilesize = 0xffffffffffff;
		if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE))
			fs->e2fs_maxfilesize = 0x7fffffffffffffff;
	}
	if (es->e4fs_flags & E2FS_UNSIGNED_HASH) {
		fs->e2fs_uhash = 3;
	} else if ((es->e4fs_flags & E2FS_SIGNED_HASH) == 0) {
#ifdef __CHAR_UNSIGNED__
		es->e4fs_flags |= E2FS_UNSIGNED_HASH;
		fs->e2fs_uhash = 3;
#else
		es->e4fs_flags |= E2FS_SIGNED_HASH;
#endif
	}
	return (0);
}
static int compute_sb_data ( struct vnode * devvp , struct ext2fs * es , struct m_ext2fs * fs ) { int db_count , error ; int i ; int logic_sb_block = 1 ; struct buf * bp ; uint32_t e2fs_descpb ; fs -> e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es -> e2fs_log_bsize ; fs -> e2fs_bsize = 1U << fs -> e2fs_bshift ; fs -> e2fs_fsbtodb = es -> e2fs_log_bsize + 1 ; fs -> e2fs_qbmask = fs -> e2fs_bsize - 1 ; fs -> e2fs_fsize = EXT2_MIN_FRAG_SIZE << es -> e2fs_log_fsize ; if ( fs -> e2fs_fsize ) fs -> e2fs_fpb = fs -> e2fs_bsize / fs -> e2fs_fsize ; fs -> e2fs_bpg = es -> e2fs_bpg ; fs -> e2fs_fpg = es -> e2fs_fpg ; fs -> e2fs_ipg = es -> e2fs_ipg ; if ( es -> e2fs_rev == E2FS_REV0 ) { fs -> e2fs_isize = E2FS_REV0_INODE_SIZE ; } else { fs -> e2fs_isize = es -> e2fs_inode_size ; if ( EXT2_INODE_SIZE ( fs ) < E2FS_REV0_INODE_SIZE || EXT2_INODE_SIZE ( fs ) > fs -> e2fs_bsize || ( fs -> e2fs_isize & ( fs -> e2fs_isize - 1 ) ) != 0 ) { printf ( " \n " , fs -> e2fs_isize ) ; return ( EIO ) ; } } if ( EXT2_HAS_RO_COMPAT_FEATURE ( fs , EXT2F_ROCOMPAT_EXTRA_ISIZE ) && EXT2_INODE_SIZE ( fs ) < sizeof ( struct ext2fs_dinode ) ) { printf ( " \n " ) ; return ( EINVAL ) ; } fs -> e2fs_ipb = fs -> e2fs_bsize / EXT2_INODE_SIZE ( fs ) ; fs -> e2fs_itpg = fs -> e2fs_ipg / fs -> e2fs_ipb ; fs -> e2fs_gcount = howmany ( es -> e2fs_bcount - es -> e2fs_first_dblock , EXT2_BLOCKS_PER_GROUP ( fs ) ) ; e2fs_descpb = fs -> e2fs_bsize / sizeof ( struct ext2_gd ) ; db_count = howmany ( fs -> e2fs_gcount , e2fs_descpb ) ; fs -> e2fs_gdbcount = db_count ; fs -> e2fs_gd = malloc ( db_count * fs -> e2fs_bsize , M_EXT2MNT , M_WAITOK ) ; fs -> e2fs_contigdirs = malloc ( fs -> e2fs_gcount * sizeof ( * fs -> e2fs_contigdirs ) , M_EXT2MNT , M_WAITOK | M_ZERO ) ; if ( fs -> e2fs_bsize > SBSIZE ) logic_sb_block = 0 ; for ( i = 0 ; i < db_count ; i ++ ) { error = bread ( devvp , fsbtodb ( fs , logic_sb_block + i + 1 ) , fs -> e2fs_bsize , NOCRED , & bp ) ; if ( error ) { free ( fs -> e2fs_contigdirs , M_EXT2MNT ) ; free ( fs -> e2fs_gd , M_EXT2MNT ) ; brelse ( bp ) ; return ( error ) ; } e2fs_cgload ( ( struct ext2_gd * ) bp -> b_data , & fs -> e2fs_gd [ i * fs -> e2fs_bsize / sizeof ( struct ext2_gd ) ] , fs -> e2fs_bsize ) ; brelse ( bp ) ; bp = NULL ; } fs -> e2fs_total_dir = 0 ; for ( i = 0 ; i < fs -> e2fs_gcount ; i ++ ) fs -> e2fs_total_dir += fs -> e2fs_gd [ i ] . ext2bgd_ndirs ; if ( es -> e2fs_rev == E2FS_REV0 || ! EXT2_HAS_RO_COMPAT_FEATURE ( fs , EXT2F_ROCOMPAT_LARGEFILE ) ) fs -> e2fs_maxfilesize = 0x7fffffff ; else { fs -> e2fs_maxfilesize = 0xffffffffffff ; if ( EXT2_HAS_RO_COMPAT_FEATURE ( fs , EXT2F_ROCOMPAT_HUGE_FILE ) ) fs -> e2fs_maxfilesize = 0x7fffffffffffffff ; } if ( es -> e4fs_flags & E2FS_UNSIGNED_HASH ) { fs -> e2fs_uhash = 3 ; } else if ( ( es -> e4fs_flags & E2FS_SIGNED_HASH ) == 0 ) { #ifdef __CHAR_UNSIGNED__ es -> e4fs_flags |= E2FS_UNSIGNED_HASH ; fs -> e2fs_uhash = 3 ; #else es -> e4fs_flags |= E2FS_SIGNED_HASH ; #endif } return ( 0 ) ; }
This computes the fields of the m_ext2fs structure from the
 data in the ext2fs structure read in.
This computes the fields of the m_ext2fs structure from the data in the ext2fs structure read in .
/* XXX for now */ /*
		 * Simple sanity check for superblock inode size value.
		 */ /* Check for extra isize in big inodes. */ /* s_resuid / s_resgid ? */ /*
	 * Adjust logic_sb_block.
	 * Godmar thinks: if the blocksize is greater than 1024, then
	 * the superblock is logically part of block zero.
	 */ /* Initialization for the ext2 Orlov allocator variant. */