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; } }
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; }