From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chao Yu Subject: Re: [RFC PATCH 4/5] mkfs.f2fs: create lost+found directory Date: Thu, 8 Feb 2018 23:08:12 +0800 Message-ID: References: <20180206043125.134191-1-shengyong1@huawei.com> <20180206043125.134191-5-shengyong1@huawei.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from sfi-mx-4.v28.ch3.sourceforge.com ([172.29.28.194] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1ejnoT-00035E-3z for linux-f2fs-devel@lists.sourceforge.net; Thu, 08 Feb 2018 15:08:37 +0000 Received: from mail.kernel.org ([198.145.29.99]) by sfi-mx-4.v28.ch3.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) id 1ejnoR-0000R1-6f for linux-f2fs-devel@lists.sourceforge.net; Thu, 08 Feb 2018 15:08:37 +0000 In-Reply-To: <20180206043125.134191-5-shengyong1@huawei.com> Content-Language: en-US List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net To: Sheng Yong , jaegeuk@kernel.org, yuchao0@huawei.com Cc: miaoxie@huawei.com, heyunlei@huawei.com, linux-f2fs-devel@lists.sourceforge.net On 2018/2/6 12:31, Sheng Yong wrote: > This patch introduces a new feature F2FS_FEATURE_LOST_FOUND. It can be > switched on by indicating a new option `lost+found' with -O. If Not sure, do we need to change this option to 'lost_found' to follow other generic -O options? > F2FS_FEATUER_LOST_FOUND is enabled, an empty directory lost+found is > created during mkfs. > > This is a preparation for fsck. During fsck, the directory is used to > save unreachable files, which have no parent directory or their parent > directory is removed by fsck. Encrypted files are also allowed to be > saved here. > > Signed-off-by: Sheng Yong > --- > fsck/mount.c | 3 + > include/f2fs_fs.h | 6 ++ > mkfs/f2fs_format.c | 223 +++++++++++++++++++++++++++++++++++++++++++++--- > mkfs/f2fs_format_main.c | 2 + > 4 files changed, 222 insertions(+), 12 deletions(-) > > diff --git a/fsck/mount.c b/fsck/mount.c > index 46cb571..df53c48 100644 > --- a/fsck/mount.c > +++ b/fsck/mount.c > @@ -460,6 +460,9 @@ void print_sb_state(struct f2fs_super_block *sb) > if (f & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME)) { > MSG(0, "%s", " inode_crtime"); > } > + if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) { > + MSG(0, "%s", " lost+found"); > + } > MSG(0, "\n"); > MSG(0, "Info: superblock encrypt level = %d, salt = ", > sb->encryption_level); > diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h > index ca4522d..093c402 100644 > --- a/include/f2fs_fs.h > +++ b/include/f2fs_fs.h > @@ -291,6 +291,8 @@ static inline uint64_t bswap_64(uint64_t val) > > #define VERSION_LEN 256 > > +#define LPF "lost+found" > + > enum f2fs_config_func { > MKFS, > FSCK, > @@ -369,6 +371,9 @@ struct f2fs_configuration { > u_int32_t next_free_nid; > u_int32_t quota_inum; > u_int32_t quota_dnum; > + u_int32_t lpf_inum; > + u_int32_t lpf_dnum; > + u_int32_t lpf_ino; > > /* defragmentation parameters */ > int defrag_shrink; > @@ -557,6 +562,7 @@ enum { > #define F2FS_FEATURE_FLEXIBLE_INLINE_XATTR 0x0040 > #define F2FS_FEATURE_QUOTA_INO 0x0080 > #define F2FS_FEATURE_INODE_CRTIME 0x0100 > +#define F2FS_FEATURE_LOST_FOUND 0x0200 > > #define MAX_VOLUME_NAME 512 > > diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c > index bda3c9d..33dd98c 100644 > --- a/mkfs/f2fs_format.c > +++ b/mkfs/f2fs_format.c > @@ -426,6 +426,9 @@ static int f2fs_prepare_super_block(void) > qtype, c.next_free_nid - 1); > } > > + if (c.feature & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) > + c.lpf_ino = c.next_free_nid++; > + > if (total_zones <= 6) { > MSG(1, "\tError: %d zones: Need more zones " > "by shrinking zone size\n", total_zones); > @@ -608,9 +611,10 @@ static int f2fs_write_check_point_pack(void) > set_cp(cur_data_segno[i], 0xffffffff); > } > > - set_cp(cur_node_blkoff[0], 1 + c.quota_inum); > - set_cp(cur_data_blkoff[0], 1 + c.quota_dnum); > - set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum); > + set_cp(cur_node_blkoff[0], 1 + c.quota_inum + c.lpf_inum); > + set_cp(cur_data_blkoff[0], 1 + c.quota_dnum + c.lpf_dnum); > + set_cp(valid_block_count, 2 + c.quota_inum + c.quota_dnum + > + c.lpf_inum + c.lpf_dnum); > set_cp(rsvd_segment_count, c.reserved_segments); > set_cp(overprov_segment_count, (get_sb(segment_count_main) - > get_cp(rsvd_segment_count)) * > @@ -642,8 +646,8 @@ static int f2fs_write_check_point_pack(void) > > set_cp(ckpt_flags, flags); > set_cp(cp_pack_start_sum, 1 + get_sb(cp_payload)); > - set_cp(valid_node_count, 1 + c.quota_inum); > - set_cp(valid_inode_count, 1 + c.quota_inum); > + set_cp(valid_node_count, 1 + c.quota_inum + c.lpf_inum); > + set_cp(valid_inode_count, 1 + c.quota_inum + c.lpf_inum); > set_cp(next_free_nid, c.next_free_nid); > set_cp(sit_ver_bitmap_bytesize, ((get_sb(segment_count_sit) / 2) << > get_sb(log_blocks_per_seg)) / 8); > @@ -702,7 +706,7 @@ static int f2fs_write_check_point_pack(void) > SET_SUM_TYPE((&sum->footer), SUM_TYPE_DATA); > > journal = &sum->journal; > - journal->n_nats = cpu_to_le16(1 + c.quota_inum); > + journal->n_nats = cpu_to_le16(1 + c.quota_inum + c.lpf_inum); > journal->nat_j.entries[0].nid = sb->root_ino; > journal->nat_j.entries[0].ne.version = 0; > journal->nat_j.entries[0].ne.ino = sb->root_ino; > @@ -723,6 +727,16 @@ static int f2fs_write_check_point_pack(void) > i++; > } > > + if (c.lpf_inum) { > + journal->nat_j.entries[i].nid = cpu_to_le32(c.lpf_ino); > + journal->nat_j.entries[i].ne.version = 0; > + journal->nat_j.entries[i].ne.ino = cpu_to_le32(c.lpf_ino); > + journal->nat_j.entries[i].ne.block_addr = cpu_to_le32( > + get_sb(main_blkaddr) + > + get_cp(cur_node_segno[0]) * > + c.blks_per_seg + i); > + } > + > memcpy(sum_compact_p, &journal->n_nats, SUM_JOURNAL_SIZE); > sum_compact_p += SUM_JOURNAL_SIZE; > > @@ -732,10 +746,13 @@ static int f2fs_write_check_point_pack(void) > journal->sit_j.entries[0].segno = cp->cur_node_segno[0]; > journal->sit_j.entries[0].se.vblocks = > cpu_to_le16((CURSEG_HOT_NODE << 10) | > - (1 + c.quota_inum)); > + (1 + c.quota_inum + c.lpf_inum)); > f2fs_set_bit(0, (char *)journal->sit_j.entries[0].se.valid_map); > for (i = 1; i <= c.quota_inum; i++) > f2fs_set_bit(i, (char *)journal->sit_j.entries[0].se.valid_map); > + if (c.lpf_inum) > + f2fs_set_bit(i, (char *)journal->sit_j.entries[0].se.valid_map); > + > journal->sit_j.entries[1].segno = cp->cur_node_segno[1]; > journal->sit_j.entries[1].se.vblocks = > cpu_to_le16((CURSEG_WARM_NODE << 10)); > @@ -747,10 +764,12 @@ static int f2fs_write_check_point_pack(void) > journal->sit_j.entries[3].segno = cp->cur_data_segno[0]; > journal->sit_j.entries[3].se.vblocks = > cpu_to_le16((CURSEG_HOT_DATA << 10) | > - (1 + c.quota_dnum)); > + (1 + c.quota_dnum + c.lpf_dnum)); > f2fs_set_bit(0, (char *)journal->sit_j.entries[3].se.valid_map); > for (i = 1; i <= c.quota_dnum; i++) > f2fs_set_bit(i, (char *)journal->sit_j.entries[3].se.valid_map); > + if (c.lpf_dnum) > + f2fs_set_bit(i, (char *)journal->sit_j.entries[3].se.valid_map); > > journal->sit_j.entries[4].segno = cp->cur_data_segno[1]; > journal->sit_j.entries[4].se.vblocks = > @@ -780,6 +799,11 @@ static int f2fs_write_check_point_pack(void) > off += QUOTA_DATA(qtype); > } > > + if (c.lpf_dnum) { > + (sum_entry + off)->nid = cpu_to_le32(c.lpf_ino); > + (sum_entry + off)->ofs_in_node = 0; > + } > + > /* warm data summary, nothing to do */ > /* cold data summary, nothing to do */ > > @@ -804,6 +828,11 @@ static int f2fs_write_check_point_pack(void) > sum->entries[1 + i].ofs_in_node = 0; > i++; > } > + if (c.lpf_inum) { > + i++; > + sum->entries[i].nid = cpu_to_le32(c.lpf_ino); > + sum->entries[i].ofs_in_node = 0; > + } > > cp_seg_blk++; > DBG(1, "\tWriting Segment summary for HOT_NODE, at offset 0x%08"PRIx64"\n", > @@ -952,7 +981,7 @@ static int discard_obsolete_dnode(struct f2fs_node *raw_node, u_int64_t offset) > > /* only root inode was written before truncating dnodes */ > last_inode_pos = start_inode_pos + > - c.cur_seg[CURSEG_HOT_NODE] * c.blks_per_seg + c.quota_inum; > + c.cur_seg[CURSEG_HOT_NODE] * c.blks_per_seg + c.quota_inum + c.lpf_inum; > > if (c.zoned_mode) > return 0; > @@ -1004,7 +1033,10 @@ static int f2fs_write_root_inode(void) > c.blks_per_seg + 1); > > raw_node->i.i_mode = cpu_to_le16(0x41ed); > - raw_node->i.i_links = cpu_to_le32(2); > + if (c.lpf_ino) > + raw_node->i.i_links = cpu_to_le32(3); > + else > + raw_node->i.i_links = cpu_to_le32(2); > raw_node->i.i_uid = cpu_to_le32(getuid()); > raw_node->i.i_gid = cpu_to_le32(getgid()); > > @@ -1121,10 +1153,16 @@ static int f2fs_write_default_quota(int qtype, unsigned int blkaddr, > dqblk.dqb_pad = cpu_to_le32(0); > dqblk.dqb_ihardlimit = cpu_to_le64(0); > dqblk.dqb_isoftlimit = cpu_to_le64(0); > - dqblk.dqb_curinodes = cpu_to_le64(1); > + if (c.lpf_ino) > + dqblk.dqb_curinodes = cpu_to_le64(2); > + else > + dqblk.dqb_curinodes = cpu_to_le64(1); > dqblk.dqb_bhardlimit = cpu_to_le64(0); > dqblk.dqb_bsoftlimit = cpu_to_le64(0); > - dqblk.dqb_curspace = cpu_to_le64(4096); > + if (c.lpf_ino) > + dqblk.dqb_curspace = cpu_to_le64(8192); > + else > + dqblk.dqb_curspace = cpu_to_le64(4096); > dqblk.dqb_btime = cpu_to_le64(0); > dqblk.dqb_itime = cpu_to_le64(0); > > @@ -1299,6 +1337,137 @@ static int f2fs_update_nat_root(void) > return 0; > } > > +static u_int64_t f2fs_add_default_dentry_lpf(void) > +{ > + struct f2fs_dentry_block *dent_blk; > + u_int64_t data_blk_offset = 0; > + > + dent_blk = calloc(F2FS_BLKSIZE, 1); > + if (dent_blk == NULL) { > + MSG(1, "\tError: Calloc Failed for dent_blk!!!\n"); > + return -1; > + } > + > + dent_blk->dentry[0].hash_code = 0; > + dent_blk->dentry[0].ino = cpu_to_le32(c.lpf_ino); > + dent_blk->dentry[0].name_len = cpu_to_le16(1); > + dent_blk->dentry[0].file_type = F2FS_FT_DIR; > + memcpy(dent_blk->filename[0], ".", 1); > + > + dent_blk->dentry[1].hash_code = 0; > + dent_blk->dentry[1].ino = sb->root_ino; > + dent_blk->dentry[1].name_len = cpu_to_le16(2); > + dent_blk->dentry[1].file_type = F2FS_FT_DIR; > + memcpy(dent_blk->filename[1], "..", 2); > + > + test_and_set_bit_le(0, dent_blk->dentry_bitmap); > + test_and_set_bit_le(1, dent_blk->dentry_bitmap); > + > + data_blk_offset = get_sb(main_blkaddr); > + data_blk_offset += c.cur_seg[CURSEG_HOT_DATA] * c.blks_per_seg + > + 1 + c.quota_dnum; > + > + DBG(1, "\tWriting default dentry lost+found, at offset 0x%08"PRIx64"\n", > + data_blk_offset); > + if (dev_write_block(dent_blk, data_blk_offset)) { > + MSG(1, "\tError While writing the dentry_blk to disk!!!\n"); > + free(dent_blk); > + return -1; > + } > + > + free(dent_blk); > + c.lpf_dnum++; > + return data_blk_offset; > +} > + > +static int f2fs_write_lpf_inode(void) > +{ > + struct f2fs_node *raw_node; > + u_int64_t blk_size_bytes, data_blk_nor; > + u_int64_t main_area_node_seg_blk_offset; > + int err = 0; > + > + ASSERT(c.lpf_ino); > + > + raw_node = calloc(F2FS_BLKSIZE, 1); > + if (raw_node == NULL) { > + MSG(1, "\tError: Calloc Failed for raw_node!!!\n"); > + return -1; > + } > + > + raw_node->footer.nid = cpu_to_le32(c.lpf_ino); > + raw_node->footer.ino = raw_node->footer.nid; > + raw_node->footer.cp_ver = cpu_to_le64(1); > + raw_node->footer.next_blkaddr = cpu_to_le32( > + get_sb(main_blkaddr) + > + c.cur_seg[CURSEG_HOT_NODE] * c.blks_per_seg + > + 1 + c.quota_inum + 1); > + > + raw_node->i.i_mode = cpu_to_le16(0x41c0); /* 0700 */ > + raw_node->i.i_links = cpu_to_le32(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); > + > + 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_pino = le32_to_cpu(sb->root_ino); > + raw_node->i.i_namelen = le32_to_cpu(strlen(LPF)); > + memcpy(raw_node->i.i_name, LPF, strlen(LPF)); > + 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); Need to handle inode_crtime case? > + > + data_blk_nor = f2fs_add_default_dentry_lpf(); > + if (data_blk_nor < 0) { > + MSG(1, "\tError: Failed to add default dentries for lost+found!!!\n"); > + err = -1; > + goto exit; > + } > + raw_node->i.i_addr[get_extra_isize(raw_node)] = cpu_to_le32(data_blk_nor); > + > + 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 + c.quota_inum + 1; > + > + DBG(1, "\tWriting lost+found 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); > + if (dev_write_block(raw_node, main_area_node_seg_blk_offset)) { > + MSG(1, "\tError: While writing the raw_node to disk!!!\n"); > + err = -1; > + goto exit; > + } > + > + c.lpf_inum++; > +exit: > + free(raw_node); > + return err; > +} > + > static int f2fs_add_default_dentry_root(void) > { > struct f2fs_dentry_block *dent_blk = NULL; > @@ -1326,6 +1495,27 @@ static int f2fs_add_default_dentry_root(void) > test_and_set_bit_le(0, dent_blk->dentry_bitmap); > test_and_set_bit_le(1, dent_blk->dentry_bitmap); > > + if (c.lpf_ino) { > + int len = strlen(LPF); > + f2fs_hash_t hash = f2fs_dentry_hash((unsigned char *)LPF, len); > + > + dent_blk->dentry[2].hash_code = cpu_to_le32(hash); > + dent_blk->dentry[2].ino = cpu_to_le32(c.lpf_ino); > + dent_blk->dentry[2].name_len = strlen(LPF); cpu_to_le16(strlen(LPF)) > + dent_blk->dentry[2].file_type = F2FS_FT_DIR; > + memcpy(dent_blk->filename[2], LPF, F2FS_SLOT_LEN); > + > + dent_blk->dentry[3].hash_code = cpu_to_le32(hash); > + dent_blk->dentry[3].ino = cpu_to_le32(c.lpf_ino); > + dent_blk->dentry[3].name_len = strlen(LPF); > + dent_blk->dentry[3].file_type = F2FS_FT_DIR; Do not need to update this whole slot? > + memcpy(dent_blk->filename[3], LPF + F2FS_SLOT_LEN, > + len - F2FS_SLOT_LEN); > + > + test_and_set_bit_le(2, dent_blk->dentry_bitmap); > + test_and_set_bit_le(3, dent_blk->dentry_bitmap); > + } > + > data_blk_offset = get_sb(main_blkaddr); > data_blk_offset += c.cur_seg[CURSEG_HOT_DATA] * > c.blks_per_seg; > @@ -1363,6 +1553,14 @@ static int f2fs_create_root_dir(void) > } > } > > + if (c.feature & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) { > + err = f2fs_write_lpf_inode(); > + if (err < 0) { > + MSG(1, "\tError: Failed to write lost+found inode!!!\n"); > + goto exit; > + } > + } > + > err = f2fs_update_nat_root(); > if (err < 0) { > MSG(1, "\tError: Failed to update NAT for root!!!\n"); > @@ -1428,6 +1626,7 @@ int f2fs_format_device(void) > MSG(0, "\tError: Failed to write the Super Block!!!\n"); > goto exit; > } > + Meaningless blank? Thanks, > exit: > if (err) > MSG(0, "\tError: Could not format the device!!!\n"); > diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c > index 120eeba..6382e71 100644 > --- a/mkfs/f2fs_format_main.c > +++ b/mkfs/f2fs_format_main.c > @@ -95,6 +95,8 @@ static void parse_feature(const char *features) > c.feature |= cpu_to_le32(F2FS_FEATURE_QUOTA_INO); > } else if (!strcmp(features, "inode_crtime")) { > c.feature |= cpu_to_le32(F2FS_FEATURE_INODE_CRTIME); > + } else if (!strcmp(features, "lost+found")) { > + c.feature |= cpu_to_le32(F2FS_FEATURE_LOST_FOUND); > } else { > MSG(0, "Error: Wrong features\n"); > mkfs_usage(); > ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot