Home | History | Annotate | Download | only in mkfs
      1 /**
      2  * f2fs_format.c
      3  *
      4  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
      5  *             http://www.samsung.com/
      6  *
      7  * Dual licensed under the GPL or LGPL version 2 licenses.
      8  */
      9 #define _LARGEFILE64_SOURCE
     10 
     11 #include <stdio.h>
     12 #include <stdlib.h>
     13 #include <fcntl.h>
     14 #include <string.h>
     15 #include <unistd.h>
     16 #include <sys/stat.h>
     17 #include <sys/mount.h>
     18 #include <time.h>
     19 #include <uuid/uuid.h>
     20 
     21 #include "f2fs_fs.h"
     22 #include "f2fs_format_utils.h"
     23 
     24 extern struct f2fs_configuration config;
     25 struct f2fs_super_block super_block;
     26 
     27 const char *media_ext_lists[] = {
     28 	"jpg",
     29 	"gif",
     30 	"png",
     31 	"avi",
     32 	"divx",
     33 	"mp4",
     34 	"mp3",
     35 	"3gp",
     36 	"wmv",
     37 	"wma",
     38 	"mpeg",
     39 	"mkv",
     40 	"mov",
     41 	"asx",
     42 	"asf",
     43 	"wmx",
     44 	"svi",
     45 	"wvx",
     46 	"wm",
     47 	"mpg",
     48 	"mpe",
     49 	"rm",
     50 	"ogg",
     51 	"jpeg",
     52 	"video",
     53 	"apk",	/* for android system */
     54 	NULL
     55 };
     56 
     57 static void configure_extension_list(void)
     58 {
     59 	const char **extlist = media_ext_lists;
     60 	char *ext_str = config.extension_list;
     61 	char *ue;
     62 	int name_len;
     63 	int i = 0;
     64 
     65 	super_block.extension_count = 0;
     66 	memset(super_block.extension_list, 0,
     67 			sizeof(super_block.extension_list));
     68 
     69 	while (*extlist) {
     70 		name_len = strlen(*extlist);
     71 		memcpy(super_block.extension_list[i++], *extlist, name_len);
     72 		extlist++;
     73 	}
     74 	super_block.extension_count = i;
     75 
     76 	if (!ext_str)
     77 		return;
     78 
     79 	/* add user ext list */
     80 	ue = strtok(ext_str, ",");
     81 	while (ue != NULL) {
     82 		name_len = strlen(ue);
     83 		memcpy(super_block.extension_list[i++], ue, name_len);
     84 		ue = strtok(NULL, ",");
     85 		if (i >= F2FS_MAX_EXTENSION)
     86 			break;
     87 	}
     88 
     89 	super_block.extension_count = i;
     90 
     91 	free(config.extension_list);
     92 }
     93 
     94 static int f2fs_prepare_super_block(void)
     95 {
     96 	u_int32_t blk_size_bytes;
     97 	u_int32_t log_sectorsize, log_sectors_per_block;
     98 	u_int32_t log_blocksize, log_blks_per_seg;
     99 	u_int32_t segment_size_bytes, zone_size_bytes;
    100 	u_int32_t sit_segments;
    101 	u_int32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa;
    102 	u_int32_t total_valid_blks_available;
    103 	u_int64_t zone_align_start_offset, diff, total_meta_segments;
    104 	u_int32_t sit_bitmap_size, max_sit_bitmap_size;
    105 	u_int32_t max_nat_bitmap_size, max_nat_segments;
    106 	u_int32_t total_zones;
    107 
    108 	super_block.magic = cpu_to_le32(F2FS_SUPER_MAGIC);
    109 	super_block.major_ver = cpu_to_le16(F2FS_MAJOR_VERSION);
    110 	super_block.minor_ver = cpu_to_le16(F2FS_MINOR_VERSION);
    111 
    112 	log_sectorsize = log_base_2(config.sector_size);
    113 	log_sectors_per_block = log_base_2(config.sectors_per_blk);
    114 	log_blocksize = log_sectorsize + log_sectors_per_block;
    115 	log_blks_per_seg = log_base_2(config.blks_per_seg);
    116 
    117 	super_block.log_sectorsize = cpu_to_le32(log_sectorsize);
    118 	super_block.log_sectors_per_block = cpu_to_le32(log_sectors_per_block);
    119 
    120 	super_block.log_blocksize = cpu_to_le32(log_blocksize);
    121 	super_block.log_blocks_per_seg = cpu_to_le32(log_blks_per_seg);
    122 
    123 	super_block.segs_per_sec = cpu_to_le32(config.segs_per_sec);
    124 	super_block.secs_per_zone = cpu_to_le32(config.secs_per_zone);
    125 	blk_size_bytes = 1 << log_blocksize;
    126 	segment_size_bytes = blk_size_bytes * config.blks_per_seg;
    127 	zone_size_bytes =
    128 		blk_size_bytes * config.secs_per_zone *
    129 		config.segs_per_sec * config.blks_per_seg;
    130 
    131 	super_block.checksum_offset = 0;
    132 
    133 	super_block.block_count = cpu_to_le64(
    134 		(config.total_sectors * DEFAULT_SECTOR_SIZE) /
    135 			blk_size_bytes);
    136 
    137 	zone_align_start_offset =
    138 		(config.start_sector * DEFAULT_SECTOR_SIZE +
    139 		2 * F2FS_BLKSIZE + zone_size_bytes - 1) /
    140 		zone_size_bytes * zone_size_bytes -
    141 		config.start_sector * DEFAULT_SECTOR_SIZE;
    142 
    143 	if (config.start_sector % DEFAULT_SECTORS_PER_BLOCK) {
    144 		MSG(1, "\tWARN: Align start sector number to the page unit\n");
    145 		MSG(1, "\ti.e., start sector: %d, ofs:%d (sects/page: %d)\n",
    146 				config.start_sector,
    147 				config.start_sector % DEFAULT_SECTORS_PER_BLOCK,
    148 				DEFAULT_SECTORS_PER_BLOCK);
    149 	}
    150 
    151 	super_block.segment_count = cpu_to_le32(
    152 		((config.total_sectors * DEFAULT_SECTOR_SIZE) -
    153 		zone_align_start_offset) / segment_size_bytes);
    154 
    155 	super_block.segment0_blkaddr =
    156 		cpu_to_le32(zone_align_start_offset / blk_size_bytes);
    157 	super_block.cp_blkaddr = super_block.segment0_blkaddr;
    158 
    159 	MSG(0, "Info: zone aligned segment0 blkaddr: %u\n",
    160 				le32_to_cpu(super_block.segment0_blkaddr));
    161 
    162 	super_block.segment_count_ckpt =
    163 				cpu_to_le32(F2FS_NUMBER_OF_CHECKPOINT_PACK);
    164 
    165 	super_block.sit_blkaddr = cpu_to_le32(
    166 		le32_to_cpu(super_block.segment0_blkaddr) +
    167 		(le32_to_cpu(super_block.segment_count_ckpt) *
    168 		(1 << log_blks_per_seg)));
    169 
    170 	blocks_for_sit = (le32_to_cpu(super_block.segment_count) +
    171 			SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK;
    172 
    173 	sit_segments = (blocks_for_sit + config.blks_per_seg - 1)
    174 			/ config.blks_per_seg;
    175 
    176 	super_block.segment_count_sit = cpu_to_le32(sit_segments * 2);
    177 
    178 	super_block.nat_blkaddr = cpu_to_le32(
    179 			le32_to_cpu(super_block.sit_blkaddr) +
    180 			(le32_to_cpu(super_block.segment_count_sit) *
    181 			 config.blks_per_seg));
    182 
    183 	total_valid_blks_available = (le32_to_cpu(super_block.segment_count) -
    184 			(le32_to_cpu(super_block.segment_count_ckpt) +
    185 			 le32_to_cpu(super_block.segment_count_sit))) *
    186 			config.blks_per_seg;
    187 
    188 	blocks_for_nat = (total_valid_blks_available + NAT_ENTRY_PER_BLOCK - 1)
    189 				/ NAT_ENTRY_PER_BLOCK;
    190 
    191 	super_block.segment_count_nat = cpu_to_le32(
    192 				(blocks_for_nat + config.blks_per_seg - 1) /
    193 				config.blks_per_seg);
    194 	/*
    195 	 * The number of node segments should not be exceeded a "Threshold".
    196 	 * This number resizes NAT bitmap area in a CP page.
    197 	 * So the threshold is determined not to overflow one CP page
    198 	 */
    199 	sit_bitmap_size = ((le32_to_cpu(super_block.segment_count_sit) / 2) <<
    200 				log_blks_per_seg) / 8;
    201 
    202 	if (sit_bitmap_size > MAX_SIT_BITMAP_SIZE)
    203 		max_sit_bitmap_size = MAX_SIT_BITMAP_SIZE;
    204 	else
    205 		max_sit_bitmap_size = sit_bitmap_size;
    206 
    207 	/*
    208 	 * It should be reserved minimum 1 segment for nat.
    209 	 * When sit is too large, we should expand cp area. It requires more pages for cp.
    210 	 */
    211 	if (max_sit_bitmap_size >
    212 			(CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 65)) {
    213 		max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1;
    214 		super_block.cp_payload = F2FS_BLK_ALIGN(max_sit_bitmap_size);
    215 	} else {
    216 		max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1
    217 			- max_sit_bitmap_size;
    218 		super_block.cp_payload = 0;
    219 	}
    220 
    221 	max_nat_segments = (max_nat_bitmap_size * 8) >> log_blks_per_seg;
    222 
    223 	if (le32_to_cpu(super_block.segment_count_nat) > max_nat_segments)
    224 		super_block.segment_count_nat = cpu_to_le32(max_nat_segments);
    225 
    226 	super_block.segment_count_nat = cpu_to_le32(
    227 			le32_to_cpu(super_block.segment_count_nat) * 2);
    228 
    229 	super_block.ssa_blkaddr = cpu_to_le32(
    230 			le32_to_cpu(super_block.nat_blkaddr) +
    231 			le32_to_cpu(super_block.segment_count_nat) *
    232 			config.blks_per_seg);
    233 
    234 	total_valid_blks_available = (le32_to_cpu(super_block.segment_count) -
    235 			(le32_to_cpu(super_block.segment_count_ckpt) +
    236 			le32_to_cpu(super_block.segment_count_sit) +
    237 			le32_to_cpu(super_block.segment_count_nat))) *
    238 			config.blks_per_seg;
    239 
    240 	blocks_for_ssa = total_valid_blks_available /
    241 				config.blks_per_seg + 1;
    242 
    243 	super_block.segment_count_ssa = cpu_to_le32(
    244 			(blocks_for_ssa + config.blks_per_seg - 1) /
    245 			config.blks_per_seg);
    246 
    247 	total_meta_segments = le32_to_cpu(super_block.segment_count_ckpt) +
    248 		le32_to_cpu(super_block.segment_count_sit) +
    249 		le32_to_cpu(super_block.segment_count_nat) +
    250 		le32_to_cpu(super_block.segment_count_ssa);
    251 	diff = total_meta_segments % (config.segs_per_sec *
    252 						config.secs_per_zone);
    253 	if (diff)
    254 		super_block.segment_count_ssa = cpu_to_le32(
    255 			le32_to_cpu(super_block.segment_count_ssa) +
    256 			(config.segs_per_sec * config.secs_per_zone -
    257 			 diff));
    258 
    259 	super_block.main_blkaddr = cpu_to_le32(
    260 			le32_to_cpu(super_block.ssa_blkaddr) +
    261 			(le32_to_cpu(super_block.segment_count_ssa) *
    262 			 config.blks_per_seg));
    263 
    264 	super_block.segment_count_main = cpu_to_le32(
    265 			le32_to_cpu(super_block.segment_count) -
    266 			(le32_to_cpu(super_block.segment_count_ckpt)
    267 			 + le32_to_cpu(super_block.segment_count_sit) +
    268 			 le32_to_cpu(super_block.segment_count_nat) +
    269 			 le32_to_cpu(super_block.segment_count_ssa)));
    270 
    271 	super_block.section_count = cpu_to_le32(
    272 			le32_to_cpu(super_block.segment_count_main)
    273 			/ config.segs_per_sec);
    274 
    275 	super_block.segment_count_main = cpu_to_le32(
    276 			le32_to_cpu(super_block.section_count) *
    277 			config.segs_per_sec);
    278 
    279 	if ((le32_to_cpu(super_block.segment_count_main) - 2) <
    280 					config.reserved_segments) {
    281 		MSG(1, "\tError: Device size is not sufficient for F2FS volume,\
    282 			more segment needed =%u",
    283 			config.reserved_segments -
    284 			(le32_to_cpu(super_block.segment_count_main) - 2));
    285 		return -1;
    286 	}
    287 
    288 	uuid_generate(super_block.uuid);
    289 
    290 	ASCIIToUNICODE(super_block.volume_name, (u_int8_t *)config.vol_label);
    291 
    292 	super_block.node_ino = cpu_to_le32(1);
    293 	super_block.meta_ino = cpu_to_le32(2);
    294 	super_block.root_ino = cpu_to_le32(3);
    295 
    296 	total_zones = le32_to_cpu(super_block.segment_count_main) /
    297 			(config.segs_per_sec * config.secs_per_zone);
    298 	if (total_zones <= 6) {
    299 		MSG(1, "\tError: %d zones: Need more zones \
    300 			by shrinking zone size\n", total_zones);
    301 		return -1;
    302 	}
    303 
    304 	if (config.heap) {
    305 		config.cur_seg[CURSEG_HOT_NODE] = (total_zones - 1) *
    306 					config.segs_per_sec *
    307 					config.secs_per_zone +
    308 					((config.secs_per_zone - 1) *
    309 					config.segs_per_sec);
    310 		config.cur_seg[CURSEG_WARM_NODE] =
    311 					config.cur_seg[CURSEG_HOT_NODE] -
    312 					config.segs_per_sec *
    313 					config.secs_per_zone;
    314 		config.cur_seg[CURSEG_COLD_NODE] =
    315 					config.cur_seg[CURSEG_WARM_NODE] -
    316 					config.segs_per_sec *
    317 					config.secs_per_zone;
    318 		config.cur_seg[CURSEG_HOT_DATA] =
    319 					config.cur_seg[CURSEG_COLD_NODE] -
    320 					config.segs_per_sec *
    321 					config.secs_per_zone;
    322 		config.cur_seg[CURSEG_COLD_DATA] = 0;
    323 		config.cur_seg[CURSEG_WARM_DATA] =
    324 					config.cur_seg[CURSEG_COLD_DATA] +
    325 					config.segs_per_sec *
    326 					config.secs_per_zone;
    327 	} else {
    328 		config.cur_seg[CURSEG_HOT_NODE] = 0;
    329 		config.cur_seg[CURSEG_WARM_NODE] =
    330 					config.cur_seg[CURSEG_HOT_NODE] +
    331 					config.segs_per_sec *
    332 					config.secs_per_zone;
    333 		config.cur_seg[CURSEG_COLD_NODE] =
    334 					config.cur_seg[CURSEG_WARM_NODE] +
    335 					config.segs_per_sec *
    336 					config.secs_per_zone;
    337 		config.cur_seg[CURSEG_HOT_DATA] =
    338 					config.cur_seg[CURSEG_COLD_NODE] +
    339 					config.segs_per_sec *
    340 					config.secs_per_zone;
    341 		config.cur_seg[CURSEG_COLD_DATA] =
    342 					config.cur_seg[CURSEG_HOT_DATA] +
    343 					config.segs_per_sec *
    344 					config.secs_per_zone;
    345 		config.cur_seg[CURSEG_WARM_DATA] =
    346 					config.cur_seg[CURSEG_COLD_DATA] +
    347 					config.segs_per_sec *
    348 					config.secs_per_zone;
    349 	}
    350 
    351 	configure_extension_list();
    352 
    353 	return 0;
    354 }
    355 
    356 static int f2fs_init_sit_area(void)
    357 {
    358 	u_int32_t blk_size, seg_size;
    359 	u_int32_t index = 0;
    360 	u_int64_t sit_seg_addr = 0;
    361 	u_int8_t *zero_buf = NULL;
    362 
    363 	blk_size = 1 << le32_to_cpu(super_block.log_blocksize);
    364 	seg_size = (1 << le32_to_cpu(super_block.log_blocks_per_seg)) *
    365 							blk_size;
    366 
    367 	zero_buf = calloc(sizeof(u_int8_t), seg_size);
    368 	if(zero_buf == NULL) {
    369 		MSG(1, "\tError: Calloc Failed for sit_zero_buf!!!\n");
    370 		return -1;
    371 	}
    372 
    373 	sit_seg_addr = le32_to_cpu(super_block.sit_blkaddr);
    374 	sit_seg_addr *= blk_size;
    375 
    376 	DBG(1, "\tFilling sit area at offset 0x%08"PRIx64"\n", sit_seg_addr);
    377 	for (index = 0;
    378 		index < (le32_to_cpu(super_block.segment_count_sit) / 2);
    379 								index++) {
    380 		if (dev_fill(zero_buf, sit_seg_addr, seg_size)) {
    381 			MSG(1, "\tError: While zeroing out the sit area \
    382 					on disk!!!\n");
    383 			return -1;
    384 		}
    385 		sit_seg_addr += seg_size;
    386 	}
    387 
    388 	free(zero_buf);
    389 	return 0 ;
    390 }
    391 
    392 static int f2fs_init_nat_area(void)
    393 {
    394 	u_int32_t blk_size, seg_size;
    395 	u_int32_t index = 0;
    396 	u_int64_t nat_seg_addr = 0;
    397 	u_int8_t *nat_buf = NULL;
    398 
    399 	blk_size = 1 << le32_to_cpu(super_block.log_blocksize);
    400 	seg_size = (1 << le32_to_cpu(super_block.log_blocks_per_seg)) *
    401 							blk_size;
    402 
    403 	nat_buf = calloc(sizeof(u_int8_t), seg_size);
    404 	if (nat_buf == NULL) {
    405 		MSG(1, "\tError: Calloc Failed for nat_zero_blk!!!\n");
    406 		return -1;
    407 	}
    408 
    409 	nat_seg_addr = le32_to_cpu(super_block.nat_blkaddr);
    410 	nat_seg_addr *= blk_size;
    411 
    412 	DBG(1, "\tFilling nat area at offset 0x%08"PRIx64"\n", nat_seg_addr);
    413 	for (index = 0;
    414 		index < (le32_to_cpu(super_block.segment_count_nat) / 2);
    415 								index++) {
    416 		if (dev_fill(nat_buf, nat_seg_addr, seg_size)) {
    417 			MSG(1, "\tError: While zeroing out the nat area \
    418 					on disk!!!\n");
    419 			return -1;
    420 		}
    421 		nat_seg_addr = nat_seg_addr + (2 * seg_size);
    422 	}
    423 
    424 	free(nat_buf);
    425 	return 0 ;
    426 }
    427 
    428 static int f2fs_write_check_point_pack(void)
    429 {
    430 	struct f2fs_checkpoint *ckp = NULL;
    431 	struct f2fs_summary_block *sum = NULL;
    432 	u_int32_t blk_size_bytes;
    433 	u_int64_t cp_seg_blk_offset = 0;
    434 	u_int32_t crc = 0;
    435 	unsigned int i;
    436 	char *cp_payload = NULL;
    437 
    438 	ckp = calloc(F2FS_BLKSIZE, 1);
    439 	if (ckp == NULL) {
    440 		MSG(1, "\tError: Calloc Failed for f2fs_checkpoint!!!\n");
    441 		return -1;
    442 	}
    443 
    444 	sum = calloc(F2FS_BLKSIZE, 1);
    445 	if (sum == NULL) {
    446 		MSG(1, "\tError: Calloc Failed for summay_node!!!\n");
    447 		return -1;
    448 	}
    449 
    450 	cp_payload = calloc(F2FS_BLKSIZE, 1);
    451 	if (cp_payload == NULL) {
    452 		MSG(1, "\tError: Calloc Failed for cp_payload!!!\n");
    453 		return -1;
    454 	}
    455 
    456 	/* 1. cp page 1 of checkpoint pack 1 */
    457 	ckp->checkpoint_ver = cpu_to_le64(1);
    458 	ckp->cur_node_segno[0] =
    459 		cpu_to_le32(config.cur_seg[CURSEG_HOT_NODE]);
    460 	ckp->cur_node_segno[1] =
    461 		cpu_to_le32(config.cur_seg[CURSEG_WARM_NODE]);
    462 	ckp->cur_node_segno[2] =
    463 		cpu_to_le32(config.cur_seg[CURSEG_COLD_NODE]);
    464 	ckp->cur_data_segno[0] =
    465 		cpu_to_le32(config.cur_seg[CURSEG_HOT_DATA]);
    466 	ckp->cur_data_segno[1] =
    467 		cpu_to_le32(config.cur_seg[CURSEG_WARM_DATA]);
    468 	ckp->cur_data_segno[2] =
    469 		cpu_to_le32(config.cur_seg[CURSEG_COLD_DATA]);
    470 	for (i = 3; i < MAX_ACTIVE_NODE_LOGS; i++) {
    471 		ckp->cur_node_segno[i] = 0xffffffff;
    472 		ckp->cur_data_segno[i] = 0xffffffff;
    473 	}
    474 
    475 	ckp->cur_node_blkoff[0] = cpu_to_le16(1);
    476 	ckp->cur_data_blkoff[0] = cpu_to_le16(1);
    477 	ckp->valid_block_count = cpu_to_le64(2);
    478 	ckp->rsvd_segment_count = cpu_to_le32(config.reserved_segments);
    479 	ckp->overprov_segment_count = cpu_to_le32(
    480 			(le32_to_cpu(super_block.segment_count_main) -
    481 			le32_to_cpu(ckp->rsvd_segment_count)) *
    482 			config.overprovision / 100);
    483 	ckp->overprov_segment_count = cpu_to_le32(
    484 			le32_to_cpu(ckp->overprov_segment_count) +
    485 			le32_to_cpu(ckp->rsvd_segment_count));
    486 
    487 	/* main segments - reserved segments - (node + data segments) */
    488 	ckp->free_segment_count = cpu_to_le32(
    489 			le32_to_cpu(super_block.segment_count_main) - 6);
    490 	ckp->user_block_count = cpu_to_le64(
    491 			((le32_to_cpu(ckp->free_segment_count) + 6 -
    492 			le32_to_cpu(ckp->overprov_segment_count)) *
    493 			 config.blks_per_seg));
    494 	ckp->cp_pack_total_block_count =
    495 		cpu_to_le32(8 + le32_to_cpu(super_block.cp_payload));
    496 	ckp->ckpt_flags = cpu_to_le32(CP_UMOUNT_FLAG);
    497 	ckp->cp_pack_start_sum = cpu_to_le32(1 + le32_to_cpu(super_block.cp_payload));
    498 	ckp->valid_node_count = cpu_to_le32(1);
    499 	ckp->valid_inode_count = cpu_to_le32(1);
    500 	ckp->next_free_nid = cpu_to_le32(
    501 			le32_to_cpu(super_block.root_ino) + 1);
    502 	ckp->sit_ver_bitmap_bytesize = cpu_to_le32(
    503 			((le32_to_cpu(super_block.segment_count_sit) / 2) <<
    504 			 le32_to_cpu(super_block.log_blocks_per_seg)) / 8);
    505 
    506 	ckp->nat_ver_bitmap_bytesize = cpu_to_le32(
    507 			((le32_to_cpu(super_block.segment_count_nat) / 2) <<
    508 			 le32_to_cpu(super_block.log_blocks_per_seg)) / 8);
    509 
    510 	ckp->checksum_offset = cpu_to_le32(CHECKSUM_OFFSET);
    511 
    512 	crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, CHECKSUM_OFFSET);
    513 	*((__le32 *)((unsigned char *)ckp + CHECKSUM_OFFSET)) =
    514 							cpu_to_le32(crc);
    515 
    516 	blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize);
    517 	cp_seg_blk_offset = le32_to_cpu(super_block.segment0_blkaddr);
    518 	cp_seg_blk_offset *= blk_size_bytes;
    519 
    520 	DBG(1, "\tWriting main segments, ckp at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    521 	if (dev_write(ckp, cp_seg_blk_offset, blk_size_bytes)) {
    522 		MSG(1, "\tError: While writing the ckp to disk!!!\n");
    523 		return -1;
    524 	}
    525 
    526 	for (i = 0; i < le32_to_cpu(super_block.cp_payload); i++) {
    527 		cp_seg_blk_offset += blk_size_bytes;
    528 		if (dev_fill(cp_payload, cp_seg_blk_offset, blk_size_bytes)) {
    529 			MSG(1, "\tError: While zeroing out the sit bitmap area \
    530 					on disk!!!\n");
    531 			return -1;
    532 		}
    533 	}
    534 
    535 	/* 2. Prepare and write Segment summary for data blocks */
    536 	memset(sum, 0, sizeof(struct f2fs_summary_block));
    537 	SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA);
    538 
    539 	sum->entries[0].nid = super_block.root_ino;
    540 	sum->entries[0].ofs_in_node = 0;
    541 
    542 	cp_seg_blk_offset += blk_size_bytes;
    543 	DBG(1, "\tWriting segment summary for data, ckp at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    544 	if (dev_write(sum, cp_seg_blk_offset, blk_size_bytes)) {
    545 		MSG(1, "\tError: While writing the sum_blk to disk!!!\n");
    546 		return -1;
    547 	}
    548 
    549 	/* 3. Fill segment summary for data block to zero. */
    550 	memset(sum, 0, sizeof(struct f2fs_summary_block));
    551 	SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA);
    552 
    553 	cp_seg_blk_offset += blk_size_bytes;
    554 	DBG(1, "\tWriting segment summary, ckp at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    555 	if (dev_write(sum, cp_seg_blk_offset, blk_size_bytes)) {
    556 		MSG(1, "\tError: While writing the sum_blk to disk!!!\n");
    557 		return -1;
    558 	}
    559 
    560 	/* 4. Fill segment summary for data block to zero. */
    561 	memset(sum, 0, sizeof(struct f2fs_summary_block));
    562 	SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA);
    563 
    564 	/* inode sit for root */
    565 	sum->n_sits = cpu_to_le16(6);
    566 	sum->sit_j.entries[0].segno = ckp->cur_node_segno[0];
    567 	sum->sit_j.entries[0].se.vblocks = cpu_to_le16((CURSEG_HOT_NODE << 10) | 1);
    568 	f2fs_set_bit(0, (char *)sum->sit_j.entries[0].se.valid_map);
    569 	sum->sit_j.entries[1].segno = ckp->cur_node_segno[1];
    570 	sum->sit_j.entries[1].se.vblocks = cpu_to_le16((CURSEG_WARM_NODE << 10));
    571 	sum->sit_j.entries[2].segno = ckp->cur_node_segno[2];
    572 	sum->sit_j.entries[2].se.vblocks = cpu_to_le16((CURSEG_COLD_NODE << 10));
    573 
    574 	/* data sit for root */
    575 	sum->sit_j.entries[3].segno = ckp->cur_data_segno[0];
    576 	sum->sit_j.entries[3].se.vblocks = cpu_to_le16((CURSEG_HOT_DATA << 10) | 1);
    577 	f2fs_set_bit(0, (char *)sum->sit_j.entries[3].se.valid_map);
    578 	sum->sit_j.entries[4].segno = ckp->cur_data_segno[1];
    579 	sum->sit_j.entries[4].se.vblocks = cpu_to_le16((CURSEG_WARM_DATA << 10));
    580 	sum->sit_j.entries[5].segno = ckp->cur_data_segno[2];
    581 	sum->sit_j.entries[5].se.vblocks = cpu_to_le16((CURSEG_COLD_DATA << 10));
    582 
    583 	cp_seg_blk_offset += blk_size_bytes;
    584 	DBG(1, "\tWriting data sit for root, at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    585 	if (dev_write(sum, cp_seg_blk_offset, blk_size_bytes)) {
    586 		MSG(1, "\tError: While writing the sum_blk to disk!!!\n");
    587 		return -1;
    588 	}
    589 
    590 	/* 5. Prepare and write Segment summary for node blocks */
    591 	memset(sum, 0, sizeof(struct f2fs_summary_block));
    592 	SET_SUM_TYPE((&sum->footer), SUM_TYPE_NODE);
    593 
    594 	sum->entries[0].nid = super_block.root_ino;
    595 	sum->entries[0].ofs_in_node = 0;
    596 
    597 	cp_seg_blk_offset += blk_size_bytes;
    598 	DBG(1, "\tWriting Segment summary for node blocks, at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    599 	if (dev_write(sum, cp_seg_blk_offset, blk_size_bytes)) {
    600 		MSG(1, "\tError: While writing the sum_blk to disk!!!\n");
    601 		return -1;
    602 	}
    603 
    604 	/* 6. Fill segment summary for data block to zero. */
    605 	memset(sum, 0, sizeof(struct f2fs_summary_block));
    606 	SET_SUM_TYPE((&sum->footer), SUM_TYPE_NODE);
    607 
    608 	cp_seg_blk_offset += blk_size_bytes;
    609 	DBG(1, "\tWriting Segment summary for data block (1/2), at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    610 	if (dev_write(sum, cp_seg_blk_offset, blk_size_bytes)) {
    611 		MSG(1, "\tError: While writing the sum_blk to disk!!!\n");
    612 		return -1;
    613 	}
    614 
    615 	/* 7. Fill segment summary for data block to zero. */
    616 	memset(sum, 0, sizeof(struct f2fs_summary_block));
    617 	SET_SUM_TYPE((&sum->footer), SUM_TYPE_NODE);
    618 	cp_seg_blk_offset += blk_size_bytes;
    619 	DBG(1, "\tWriting Segment summary for data block (2/2), at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    620 	if (dev_write(sum, cp_seg_blk_offset, blk_size_bytes)) {
    621 		MSG(1, "\tError: While writing the sum_blk to disk!!!\n");
    622 		return -1;
    623 	}
    624 
    625 	/* 8. cp page2 */
    626 	cp_seg_blk_offset += blk_size_bytes;
    627 	DBG(1, "\tWriting cp page2, at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    628 	if (dev_write(ckp, cp_seg_blk_offset, blk_size_bytes)) {
    629 		MSG(1, "\tError: While writing the ckp to disk!!!\n");
    630 		return -1;
    631 	}
    632 
    633 	/* 9. cp page 1 of check point pack 2
    634 	 * Initiatialize other checkpoint pack with version zero
    635 	 */
    636 	ckp->checkpoint_ver = 0;
    637 
    638 	crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, CHECKSUM_OFFSET);
    639 	*((__le32 *)((unsigned char *)ckp + CHECKSUM_OFFSET)) =
    640 							cpu_to_le32(crc);
    641 	cp_seg_blk_offset = (le32_to_cpu(super_block.segment0_blkaddr) +
    642 				config.blks_per_seg) *
    643 				blk_size_bytes;
    644 	DBG(1, "\tWriting cp page 1 of checkpoint pack 2, at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    645 	if (dev_write(ckp, cp_seg_blk_offset, blk_size_bytes)) {
    646 		MSG(1, "\tError: While writing the ckp to disk!!!\n");
    647 		return -1;
    648 	}
    649 
    650 	for (i = 0; i < le32_to_cpu(super_block.cp_payload); i++) {
    651 		cp_seg_blk_offset += blk_size_bytes;
    652 		if (dev_fill(cp_payload, cp_seg_blk_offset, blk_size_bytes)) {
    653 			MSG(1, "\tError: While zeroing out the sit bitmap area \
    654 					on disk!!!\n");
    655 			return -1;
    656 		}
    657 	}
    658 
    659 	/* 10. cp page 2 of check point pack 2 */
    660 	cp_seg_blk_offset += blk_size_bytes * (le32_to_cpu(ckp->cp_pack_total_block_count)
    661 			- le32_to_cpu(super_block.cp_payload) - 1);
    662 	DBG(1, "\tWriting cp page 2 of checkpoint pack 2, at offset 0x%08"PRIx64"\n", cp_seg_blk_offset);
    663 	if (dev_write(ckp, cp_seg_blk_offset, blk_size_bytes)) {
    664 		MSG(1, "\tError: While writing the ckp to disk!!!\n");
    665 		return -1;
    666 	}
    667 
    668 	free(sum) ;
    669 	free(ckp) ;
    670 	free(cp_payload);
    671 	return	0;
    672 }
    673 
    674 static int f2fs_write_super_block(void)
    675 {
    676 	int index;
    677 	u_int8_t *zero_buff;
    678 
    679 	zero_buff = calloc(F2FS_BLKSIZE, 1);
    680 
    681 	memcpy(zero_buff + F2FS_SUPER_OFFSET, &super_block,
    682 						sizeof(super_block));
    683 	DBG(1, "\tWriting super block, at offset 0x%08x\n", 0);
    684 	for (index = 0; index < 2; index++) {
    685 		if (dev_write(zero_buff, index * F2FS_BLKSIZE, F2FS_BLKSIZE)) {
    686 			MSG(1, "\tError: While while writing supe_blk \
    687 					on disk!!! index : %d\n", index);
    688 			return -1;
    689 		}
    690 	}
    691 
    692 	free(zero_buff);
    693 	return 0;
    694 }
    695 
    696 static int f2fs_write_root_inode(void)
    697 {
    698 	struct f2fs_node *raw_node = NULL;
    699 	u_int64_t blk_size_bytes, data_blk_nor;
    700 	u_int64_t main_area_node_seg_blk_offset = 0;
    701 
    702 	raw_node = calloc(F2FS_BLKSIZE, 1);
    703 	if (raw_node == NULL) {
    704 		MSG(1, "\tError: Calloc Failed for raw_node!!!\n");
    705 		return -1;
    706 	}
    707 
    708 	raw_node->footer.nid = super_block.root_ino;
    709 	raw_node->footer.ino = super_block.root_ino;
    710 	raw_node->footer.cp_ver = cpu_to_le64(1);
    711 	raw_node->footer.next_blkaddr = cpu_to_le32(
    712 			le32_to_cpu(super_block.main_blkaddr) +
    713 			config.cur_seg[CURSEG_HOT_NODE] *
    714 			config.blks_per_seg + 1);
    715 
    716 	raw_node->i.i_mode = cpu_to_le16(0x41ed);
    717 	raw_node->i.i_links = cpu_to_le32(2);
    718 	raw_node->i.i_uid = cpu_to_le32(getuid());
    719 	raw_node->i.i_gid = cpu_to_le32(getgid());
    720 
    721 	blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize);
    722 	raw_node->i.i_size = cpu_to_le64(1 * blk_size_bytes); /* dentry */
    723 	raw_node->i.i_blocks = cpu_to_le64(2);
    724 
    725 	raw_node->i.i_atime = cpu_to_le32(time(NULL));
    726 	raw_node->i.i_atime_nsec = 0;
    727 	raw_node->i.i_ctime = cpu_to_le32(time(NULL));
    728 	raw_node->i.i_ctime_nsec = 0;
    729 	raw_node->i.i_mtime = cpu_to_le32(time(NULL));
    730 	raw_node->i.i_mtime_nsec = 0;
    731 	raw_node->i.i_generation = 0;
    732 	raw_node->i.i_xattr_nid = 0;
    733 	raw_node->i.i_flags = 0;
    734 	raw_node->i.i_current_depth = cpu_to_le32(1);
    735 	raw_node->i.i_dir_level = DEF_DIR_LEVEL;
    736 
    737 	data_blk_nor = le32_to_cpu(super_block.main_blkaddr) +
    738 		config.cur_seg[CURSEG_HOT_DATA] * config.blks_per_seg;
    739 	raw_node->i.i_addr[0] = cpu_to_le32(data_blk_nor);
    740 
    741 	raw_node->i.i_ext.fofs = 0;
    742 	raw_node->i.i_ext.blk_addr = cpu_to_le32(data_blk_nor);
    743 	raw_node->i.i_ext.len = cpu_to_le32(1);
    744 
    745 	main_area_node_seg_blk_offset = le32_to_cpu(super_block.main_blkaddr);
    746 	main_area_node_seg_blk_offset += config.cur_seg[CURSEG_HOT_NODE] *
    747 					config.blks_per_seg;
    748         main_area_node_seg_blk_offset *= blk_size_bytes;
    749 
    750 	DBG(1, "\tWriting root inode (hot node), at offset 0x%08"PRIx64"\n", main_area_node_seg_blk_offset);
    751 	if (dev_write(raw_node, main_area_node_seg_blk_offset, F2FS_BLKSIZE)) {
    752 		MSG(1, "\tError: While writing the raw_node to disk!!!\n");
    753 		return -1;
    754 	}
    755 
    756 	memset(raw_node, 0xff, sizeof(struct f2fs_node));
    757 
    758 	/* avoid power-off-recovery based on roll-forward policy */
    759 	main_area_node_seg_blk_offset = le32_to_cpu(super_block.main_blkaddr);
    760 	main_area_node_seg_blk_offset += config.cur_seg[CURSEG_WARM_NODE] *
    761 					config.blks_per_seg;
    762         main_area_node_seg_blk_offset *= blk_size_bytes;
    763 
    764 	DBG(1, "\tWriting root inode (warm node), at offset 0x%08"PRIx64"\n", main_area_node_seg_blk_offset);
    765 	if (dev_write(raw_node, main_area_node_seg_blk_offset, F2FS_BLKSIZE)) {
    766 		MSG(1, "\tError: While writing the raw_node to disk!!!\n");
    767 		return -1;
    768 	}
    769 	free(raw_node);
    770 	return 0;
    771 }
    772 
    773 static int f2fs_update_nat_root(void)
    774 {
    775 	struct f2fs_nat_block *nat_blk = NULL;
    776 	u_int64_t blk_size_bytes, nat_seg_blk_offset = 0;
    777 
    778 	nat_blk = calloc(F2FS_BLKSIZE, 1);
    779 	if(nat_blk == NULL) {
    780 		MSG(1, "\tError: Calloc Failed for nat_blk!!!\n");
    781 		return -1;
    782 	}
    783 
    784 	/* update root */
    785 	nat_blk->entries[le32_to_cpu(super_block.root_ino)].block_addr = cpu_to_le32(
    786 		le32_to_cpu(super_block.main_blkaddr) +
    787 		config.cur_seg[CURSEG_HOT_NODE] * config.blks_per_seg);
    788 	nat_blk->entries[le32_to_cpu(super_block.root_ino)].ino = super_block.root_ino;
    789 
    790 	/* update node nat */
    791 	nat_blk->entries[le32_to_cpu(super_block.node_ino)].block_addr = cpu_to_le32(1);
    792 	nat_blk->entries[le32_to_cpu(super_block.node_ino)].ino = super_block.node_ino;
    793 
    794 	/* update meta nat */
    795 	nat_blk->entries[le32_to_cpu(super_block.meta_ino)].block_addr = cpu_to_le32(1);
    796 	nat_blk->entries[le32_to_cpu(super_block.meta_ino)].ino = super_block.meta_ino;
    797 
    798 	blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize);
    799 	nat_seg_blk_offset = le32_to_cpu(super_block.nat_blkaddr);
    800 	nat_seg_blk_offset *= blk_size_bytes;
    801 
    802 	DBG(1, "\tWriting nat root, at offset 0x%08"PRIx64"\n", nat_seg_blk_offset);
    803 	if (dev_write(nat_blk, nat_seg_blk_offset, F2FS_BLKSIZE)) {
    804 		MSG(1, "\tError: While writing the nat_blk set0 to disk!\n");
    805 		return -1;
    806 	}
    807 
    808 	free(nat_blk);
    809 	return 0;
    810 }
    811 
    812 static int f2fs_add_default_dentry_root(void)
    813 {
    814 	struct f2fs_dentry_block *dent_blk = NULL;
    815 	u_int64_t blk_size_bytes, data_blk_offset = 0;
    816 
    817 	dent_blk = calloc(F2FS_BLKSIZE, 1);
    818 	if(dent_blk == NULL) {
    819 		MSG(1, "\tError: Calloc Failed for dent_blk!!!\n");
    820 		return -1;
    821 	}
    822 
    823 	dent_blk->dentry[0].hash_code = 0;
    824 	dent_blk->dentry[0].ino = super_block.root_ino;
    825 	dent_blk->dentry[0].name_len = cpu_to_le16(1);
    826 	dent_blk->dentry[0].file_type = F2FS_FT_DIR;
    827 	memcpy(dent_blk->filename[0], ".", 1);
    828 
    829 	dent_blk->dentry[1].hash_code = 0;
    830 	dent_blk->dentry[1].ino = super_block.root_ino;
    831 	dent_blk->dentry[1].name_len = cpu_to_le16(2);
    832 	dent_blk->dentry[1].file_type = F2FS_FT_DIR;
    833 	memcpy(dent_blk->filename[1], "..", 2);
    834 
    835 	/* bitmap for . and .. */
    836 	dent_blk->dentry_bitmap[0] = (1 << 1) | (1 << 0);
    837 	blk_size_bytes = 1 << le32_to_cpu(super_block.log_blocksize);
    838 	data_blk_offset = le32_to_cpu(super_block.main_blkaddr);
    839 	data_blk_offset += config.cur_seg[CURSEG_HOT_DATA] *
    840 				config.blks_per_seg;
    841 	data_blk_offset *= blk_size_bytes;
    842 
    843 	DBG(1, "\tWriting default dentry root, at offset 0x%08"PRIx64"\n", data_blk_offset);
    844 	if (dev_write(dent_blk, data_blk_offset, F2FS_BLKSIZE)) {
    845 		MSG(1, "\tError: While writing the dentry_blk to disk!!!\n");
    846 		return -1;
    847 	}
    848 
    849 	free(dent_blk);
    850 	return 0;
    851 }
    852 
    853 static int f2fs_create_root_dir(void)
    854 {
    855 	int err = 0;
    856 
    857 	err = f2fs_write_root_inode();
    858 	if (err < 0) {
    859 		MSG(1, "\tError: Failed to write root inode!!!\n");
    860 		goto exit;
    861 	}
    862 
    863 	err = f2fs_update_nat_root();
    864 	if (err < 0) {
    865 		MSG(1, "\tError: Failed to update NAT for root!!!\n");
    866 		goto exit;
    867 	}
    868 
    869 	err = f2fs_add_default_dentry_root();
    870 	if (err < 0) {
    871 		MSG(1, "\tError: Failed to add default dentries for root!!!\n");
    872 		goto exit;
    873 	}
    874 exit:
    875 	if (err)
    876 		MSG(1, "\tError: Could not create the root directory!!!\n");
    877 
    878 	return err;
    879 }
    880 
    881 int f2fs_format_device(void)
    882 {
    883 	int err = 0;
    884 
    885 	err= f2fs_prepare_super_block();
    886 	if (err < 0) {
    887 		MSG(0, "\tError: Failed to prepare a super block!!!\n");
    888 		goto exit;
    889 	}
    890 
    891 	err = f2fs_trim_device();
    892 	if (err < 0) {
    893 		MSG(0, "\tError: Failed to trim whole device!!!\n");
    894 		goto exit;
    895 	}
    896 
    897 	err = f2fs_init_sit_area();
    898 	if (err < 0) {
    899 		MSG(0, "\tError: Failed to Initialise the SIT AREA!!!\n");
    900 		goto exit;
    901 	}
    902 
    903 	err = f2fs_init_nat_area();
    904 	if (err < 0) {
    905 		MSG(0, "\tError: Failed to Initialise the NAT AREA!!!\n");
    906 		goto exit;
    907 	}
    908 
    909 	err = f2fs_create_root_dir();
    910 	if (err < 0) {
    911 		MSG(0, "\tError: Failed to create the root directory!!!\n");
    912 		goto exit;
    913 	}
    914 
    915 	err = f2fs_write_check_point_pack();
    916 	if (err < 0) {
    917 		MSG(0, "\tError: Failed to write the check point pack!!!\n");
    918 		goto exit;
    919 	}
    920 
    921 	err = f2fs_write_super_block();
    922 	if (err < 0) {
    923 		MSG(0, "\tError: Failed to write the Super Block!!!\n");
    924 		goto exit;
    925 	}
    926 exit:
    927 	if (err)
    928 		MSG(0, "\tError: Could not format the device!!!\n");
    929 
    930 	return err;
    931 }
    932