前面两篇文章写了f2fs format过程中superblock 和 cp填充的过程,格式化过程中主要是这两个meta data的填充有点不好理解,后面的部分相对来说比较容易,本篇说说后面的部分做的内容。
1, f2fs_init_sit_area()
static int f2fs_init_sit_area(void)
{
u_int32_t blk_size, seg_size;
u_int32_t index = 0;
u_int64_t sit_seg_addr = 0;
u_int8_t *zero_buf = NULL;
//首先获得block和segment的size
blk_size = 1 << get_sb(log_blocksize);
seg_size = (1 << get_sb(log_blocks_per_seg)) * blk_size;
zero_buf = calloc(sizeof(u_int8_t), seg_size);
if(zero_buf == NULL) {
MSG(1, "\tError: Calloc Failed for sit_zero_buf!!!\n");
return -1;
}
//得到sit area的起始地址
sit_seg_addr = get_sb(sit_blkaddr);
sit_seg_addr *= blk_size;
//将sit area全部置0
DBG(1, "\tFilling sit area at offset 0x%08"PRIx64"\n", sit_seg_addr);
for (index = 0; index < (get_sb(segment_count_sit) / 2); index++) {
if (dev_fill(zero_buf, sit_seg_addr, seg_size)) {
MSG(1, "\tError: While zeroing out the sit area "
"on disk!!!\n");
free(zero_buf);
return -1;
}
sit_seg_addr += seg_size;
}
free(zero_buf);
return 0 ;
}
2, 同样的方法,将nat area清0
static int f2fs_init_nat_area(void)
{
u_int32_t blk_size, seg_size;
u_int32_t index = 0;
u_int64_t nat_seg_addr = 0;
u_int8_t *nat_buf = NULL;
blk_size = 1 << get_sb(log_blocksize);
seg_size = (1 << get_sb(log_blocks_per_seg)) * blk_size;
nat_buf = calloc(sizeof(u_int8_t), seg_size);
if (nat_buf == NULL) {
MSG(1, "\tError: Calloc Failed for nat_zero_blk!!!\n");
return -1;
}
nat_seg_addr = get_sb(nat_blkaddr);
nat_seg_addr *= blk_size;
DBG(1, "\tFilling nat area at offset 0x%08"PRIx64"\n", nat_seg_addr);
for (index = 0; index < get_sb(segment_count_nat) / 2; index++) {
if (dev_fill(nat_buf, nat_seg_addr, seg_size)) {
MSG(1, "\tError: While zeroing out the nat area "
"on disk!!!\n");
free(nat_buf);
return -1;
}
nat_seg_addr = nat_seg_addr + (2 * seg_size);
}
free(nat_buf);
return 0 ;
}
3, 第在个比较重要的是create root dir:
static int f2fs_write_root_inode(void)
{
struct f2fs_node *raw_node = NULL;
u_int64_t blk_size_bytes, data_blk_nor;
u_int64_t main_area_node_seg_blk_offset = 0;
raw_node = calloc(F2FS_BLKSIZE, 1);
if (raw_node == NULL) {
MSG(1, "\tError: Calloc Failed for raw_node!!!\n");
return -1;
}
//
//设置root inode block
raw_node->footer.nid = sb->root_ino;
raw_node->footer.ino = sb->root_ino;
raw_node->footer.cp_ver = cpu_to_le64(1);
//设置root inode 后的block address
raw_node->footer.next_blkaddr = cpu_to_le32(
get_sb(main_blkaddr) +
c.cur_seg[CURSEG_HOT_NODE] *
c.blks_per_seg + 1);
raw_node->i.i_mode = cpu_to_le16(0x41ed);
if (c.lpf_ino)
raw_node->i.i_links = cpu_to_le32(3);
else
raw_node->i.i_links = cpu_to_le32(2);//links count 2
raw_node->i.i_uid = cpu_to_le32(getuid());
raw_node->i.i_gid = cpu_to_le32(getgid());
blk_size_bytes = 1 << get_sb(log_blocksize);
raw_node->i.i_size = cpu_to_le64(1 * blk_size_bytes); /* dentry */
raw_node->i.i_blocks = cpu_to_le64(2);// 2 blocks,1 node inode, 1 data node
raw_node->i.i_atime = cpu_to_le32(time(NULL));
raw_node->i.i_atime_nsec = 0;
raw_node->i.i_ctime = cpu_to_le32(time(NULL));
raw_node->i.i_ctime_nsec = 0;
raw_node->i.i_mtime = cpu_to_le32(time(NULL));
raw_node->i.i_mtime_nsec = 0;
raw_node->i.i_generation = 0;
raw_node->i.i_xattr_nid = 0;
raw_node->i.i_flags = 0;
raw_node->i.i_current_depth = cpu_to_le32(1);
raw_node->i.i_dir_level = DEF_DIR_LEVEL;
if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
raw_node->i.i_inline = F2FS_EXTRA_ATTR;
raw_node->i.i_extra_isize =
cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
}
if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA))
raw_node->i.i_projid = cpu_to_le32(F2FS_DEF_PROJID);
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) {
raw_node->i.i_crtime = cpu_to_le32(time(NULL));
raw_node->i.i_crtime_nsec = 0;
}
//data block address
data_blk_nor = get_sb(main_blkaddr) +
c.cur_seg[CURSEG_HOT_DATA] * c.blks_per_seg;
//设置i_addr指向data block address
raw_node->i.i_addr[get_extra_isize(raw_node)] = cpu_to_le32(data_blk_nor);
raw_node->i.i_ext.fofs = 0;
raw_node->i.i_ext.blk_addr = 0;
raw_node->i.i_ext.len = 0;
if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
raw_node->i.i_inode_checksum =
cpu_to_le32(f2fs_inode_chksum(raw_node));
main_area_node_seg_blk_offset = get_sb(main_blkaddr);
main_area_node_seg_blk_offset += c.cur_seg[CURSEG_HOT_NODE] *
c.blks_per_seg;
DBG(1, "\tWriting root inode (hot node), %x %x %x at offset 0x%08"PRIu64"\n",
get_sb(main_blkaddr),
c.cur_seg[CURSEG_HOT_NODE],
c.blks_per_seg, main_area_node_seg_blk_offset);
//将root inode block 写回
if (dev_write_block(raw_node, main_area_node_seg_blk_offset)) {
MSG(1, "\tError: While writing the raw_node to disk!!!\n");
free(raw_node);
return -1;
}
free(raw_node);
return 0;
}