Пример #1
0
void inicializar_cache(const configuracion* conf)
{
    int i, j;

    num_conjuntos = conf->num_lineas / conf->asociatividad;
    asociatividad = conf->asociatividad;
    es_lru = conf->reemplazo;

    num_bits_offset = log_base_2(conf->tamano_linea);
    num_bits_indice = log_base_2(num_conjuntos);
    num_bits_etiqueta = 32 - num_bits_offset - num_bits_indice;

    /* inicializamos la caché, de forma que todas las líneas esten disponibles */
    cache = __malloc(linea*, num_conjuntos);
    for(i = 0; i != num_conjuntos; ++i)
        cache[i] = __malloc(linea, asociatividad);

    for(i = 0;i != num_conjuntos; ++i)
        for(j = 0; j != asociatividad; ++j)
        {
            linea* l = &cache[i][j];
            l->contador_lru = 1;
            l->valido = 0;
        }
}
Пример #2
0
static int f2fs_prepare_super_block(void)
{
	u_int32_t blk_size_bytes;
	u_int32_t log_sectorsize, log_sectors_per_block;
	u_int32_t log_blocksize, log_blks_per_seg;
	u_int32_t segment_size_bytes, zone_size_bytes;
	u_int32_t sit_segments;
	u_int32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa;
	u_int32_t total_valid_blks_available;
	u_int64_t zone_align_start_offset, diff, total_meta_segments;
	u_int32_t sit_bitmap_size, max_sit_bitmap_size;
	u_int32_t max_nat_bitmap_size, max_nat_segments;
	u_int32_t total_zones;

	super_block.magic = cpu_to_le32(F2FS_SUPER_MAGIC);
	super_block.major_ver = cpu_to_le16(F2FS_MAJOR_VERSION);
	super_block.minor_ver = cpu_to_le16(F2FS_MINOR_VERSION);

	log_sectorsize = log_base_2(config.sector_size);
	log_sectors_per_block = log_base_2(config.sectors_per_blk);
	log_blocksize = log_sectorsize + log_sectors_per_block;
	log_blks_per_seg = log_base_2(config.blks_per_seg);

	super_block.log_sectorsize = cpu_to_le32(log_sectorsize);
	super_block.log_sectors_per_block = cpu_to_le32(log_sectors_per_block);

	super_block.log_blocksize = cpu_to_le32(log_blocksize);
	super_block.log_blocks_per_seg = cpu_to_le32(log_blks_per_seg);

	super_block.segs_per_sec = cpu_to_le32(config.segs_per_sec);
	super_block.secs_per_zone = cpu_to_le32(config.secs_per_zone);
	blk_size_bytes = 1 << log_blocksize;
	segment_size_bytes = blk_size_bytes * config.blks_per_seg;
	zone_size_bytes =
		blk_size_bytes * config.secs_per_zone *
		config.segs_per_sec * config.blks_per_seg;

	super_block.checksum_offset = 0;

	super_block.block_count = cpu_to_le64(
		(config.total_sectors * DEFAULT_SECTOR_SIZE) /
			blk_size_bytes);

	zone_align_start_offset =
		(config.start_sector * DEFAULT_SECTOR_SIZE +
		2 * F2FS_BLKSIZE + zone_size_bytes - 1) /
		zone_size_bytes * zone_size_bytes -
		config.start_sector * DEFAULT_SECTOR_SIZE;

	if (config.start_sector % DEFAULT_SECTORS_PER_BLOCK) {
		MSG(1, "\tWARN: Align start sector number to the page unit\n");
		MSG(1, "\ti.e., start sector: %d, ofs:%d (sects/page: %d)\n",
				config.start_sector,
				config.start_sector % DEFAULT_SECTORS_PER_BLOCK,
				DEFAULT_SECTORS_PER_BLOCK);
	}

	super_block.segment_count = cpu_to_le32(
		((config.total_sectors * DEFAULT_SECTOR_SIZE) -
		zone_align_start_offset) / segment_size_bytes);

	super_block.segment0_blkaddr =
		cpu_to_le32(zone_align_start_offset / blk_size_bytes);
	super_block.cp_blkaddr = super_block.segment0_blkaddr;

	MSG(0, "Info: zone aligned segment0 blkaddr: %u\n",
				le32_to_cpu(super_block.segment0_blkaddr));

	super_block.segment_count_ckpt =
				cpu_to_le32(F2FS_NUMBER_OF_CHECKPOINT_PACK);

	super_block.sit_blkaddr = cpu_to_le32(
		le32_to_cpu(super_block.segment0_blkaddr) +
		(le32_to_cpu(super_block.segment_count_ckpt) *
		(1 << log_blks_per_seg)));

	blocks_for_sit = (le32_to_cpu(super_block.segment_count) +
			SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK;

	sit_segments = (blocks_for_sit + config.blks_per_seg - 1)
			/ config.blks_per_seg;

	super_block.segment_count_sit = cpu_to_le32(sit_segments * 2);

	super_block.nat_blkaddr = cpu_to_le32(
			le32_to_cpu(super_block.sit_blkaddr) +
			(le32_to_cpu(super_block.segment_count_sit) *
			 config.blks_per_seg));

	total_valid_blks_available = (le32_to_cpu(super_block.segment_count) -
			(le32_to_cpu(super_block.segment_count_ckpt) +
			 le32_to_cpu(super_block.segment_count_sit))) *
			config.blks_per_seg;

	blocks_for_nat = (total_valid_blks_available + NAT_ENTRY_PER_BLOCK - 1)
				/ NAT_ENTRY_PER_BLOCK;

	super_block.segment_count_nat = cpu_to_le32(
				(blocks_for_nat + config.blks_per_seg - 1) /
				config.blks_per_seg);
	/*
	 * The number of node segments should not be exceeded a "Threshold".
	 * This number resizes NAT bitmap area in a CP page.
	 * So the threshold is determined not to overflow one CP page
	 */
	sit_bitmap_size = ((le32_to_cpu(super_block.segment_count_sit) / 2) <<
				log_blks_per_seg) / 8;

	if (sit_bitmap_size > MAX_SIT_BITMAP_SIZE)
		max_sit_bitmap_size = MAX_SIT_BITMAP_SIZE;
	else
		max_sit_bitmap_size = sit_bitmap_size;

	/*
	 * It should be reserved minimum 1 segment for nat.
	 * When sit is too large, we should expand cp area. It requires more pages for cp.
	 */
	if (max_sit_bitmap_size >
			(CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 65)) {
		max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1;
		super_block.cp_payload = F2FS_BLK_ALIGN(max_sit_bitmap_size);
	} else {
		max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1
			- max_sit_bitmap_size;
		super_block.cp_payload = 0;
	}

	max_nat_segments = (max_nat_bitmap_size * 8) >> log_blks_per_seg;

	if (le32_to_cpu(super_block.segment_count_nat) > max_nat_segments)
		super_block.segment_count_nat = cpu_to_le32(max_nat_segments);

	super_block.segment_count_nat = cpu_to_le32(
			le32_to_cpu(super_block.segment_count_nat) * 2);

	super_block.ssa_blkaddr = cpu_to_le32(
			le32_to_cpu(super_block.nat_blkaddr) +
			le32_to_cpu(super_block.segment_count_nat) *
			config.blks_per_seg);

	total_valid_blks_available = (le32_to_cpu(super_block.segment_count) -
			(le32_to_cpu(super_block.segment_count_ckpt) +
			le32_to_cpu(super_block.segment_count_sit) +
			le32_to_cpu(super_block.segment_count_nat))) *
			config.blks_per_seg;

	blocks_for_ssa = total_valid_blks_available /
				config.blks_per_seg + 1;

	super_block.segment_count_ssa = cpu_to_le32(
			(blocks_for_ssa + config.blks_per_seg - 1) /
			config.blks_per_seg);

	total_meta_segments = le32_to_cpu(super_block.segment_count_ckpt) +
		le32_to_cpu(super_block.segment_count_sit) +
		le32_to_cpu(super_block.segment_count_nat) +
		le32_to_cpu(super_block.segment_count_ssa);
	diff = total_meta_segments % (config.segs_per_sec *
						config.secs_per_zone);
	if (diff)
		super_block.segment_count_ssa = cpu_to_le32(
			le32_to_cpu(super_block.segment_count_ssa) +
			(config.segs_per_sec * config.secs_per_zone -
			 diff));

	super_block.main_blkaddr = cpu_to_le32(
			le32_to_cpu(super_block.ssa_blkaddr) +
			(le32_to_cpu(super_block.segment_count_ssa) *
			 config.blks_per_seg));

	super_block.segment_count_main = cpu_to_le32(
			le32_to_cpu(super_block.segment_count) -
			(le32_to_cpu(super_block.segment_count_ckpt)
			 + le32_to_cpu(super_block.segment_count_sit) +
			 le32_to_cpu(super_block.segment_count_nat) +
			 le32_to_cpu(super_block.segment_count_ssa)));

	super_block.section_count = cpu_to_le32(
			le32_to_cpu(super_block.segment_count_main)
			/ config.segs_per_sec);

	super_block.segment_count_main = cpu_to_le32(
			le32_to_cpu(super_block.section_count) *
			config.segs_per_sec);

	if ((le32_to_cpu(super_block.segment_count_main) - 2) <
					config.reserved_segments) {
		MSG(1, "\tError: Device size is not sufficient for F2FS volume,\
			more segment needed =%u",
			config.reserved_segments -
			(le32_to_cpu(super_block.segment_count_main) - 2));
		return -1;
	}