f2fs_sparseblock.c revision aff4a27b96454d6868a7a22974f560147a13188f
102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#define _LARGEFILE64_SOURCE 202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#define LOG_TAG "f2fs_sparseblock" 402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#include <cutils/log.h> 702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#include <fcntl.h> 802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#include <f2fs_fs.h> 902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#include <linux/types.h> 1002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#include <sys/stat.h> 1102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#include "f2fs_sparseblock.h" 1202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 1302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 1402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#define D_DISP_u32(ptr, member) \ 1502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg do { \ 1602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("%-30s" "\t\t[0x%#08x : %u]\n", \ 1702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg #member, le32_to_cpu((ptr)->member), le32_to_cpu((ptr)->member) ); \ 1802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } while (0); 1902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 2002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#define D_DISP_u64(ptr, member) \ 2102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg do { \ 2202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("%-30s" "\t\t[0x%#016llx : %llu]\n", \ 2302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg #member, le64_to_cpu((ptr)->member), le64_to_cpu((ptr)->member) ); \ 2402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } while (0); 2502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 2602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic void dbg_print_raw_sb_info(struct f2fs_super_block *sb) 2702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 2802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("\n"); 2902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("+--------------------------------------------------------+\n"); 3002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("| Super block |\n"); 3102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("+--------------------------------------------------------+\n"); 3202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 3302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, magic); 3402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, major_ver); 3502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, minor_ver); 3602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, log_sectorsize); 3702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, log_sectors_per_block); 3802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 3902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, log_blocksize); 4002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, log_blocks_per_seg); 4102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segs_per_sec); 4202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, secs_per_zone); 4302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, checksum_offset); 4402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u64(sb, block_count); 4502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 4602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, section_count); 4702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment_count); 4802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment_count_ckpt); 4902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment_count_sit); 5002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment_count_nat); 5102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 5202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment_count_ssa); 5302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment_count_main); 5402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, segment0_blkaddr); 5502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 5602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, cp_blkaddr); 5702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, sit_blkaddr); 5802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, nat_blkaddr); 5902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, ssa_blkaddr); 6002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, main_blkaddr); 6102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 6202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, root_ino); 6302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, node_ino); 6402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, meta_ino); 6502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(sb, cp_payload); 6602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("\n"); 6702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 6802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic void dbg_print_raw_ckpt_struct(struct f2fs_checkpoint *cp) 6902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 7002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("\n"); 7102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("+--------------------------------------------------------+\n"); 7202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("| Checkpoint |\n"); 7302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("+--------------------------------------------------------+\n"); 7402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 7502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u64(cp, checkpoint_ver); 7602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u64(cp, user_block_count); 7702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u64(cp, valid_block_count); 7802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, rsvd_segment_count); 7902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, overprov_segment_count); 8002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, free_segment_count); 8102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 8202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, alloc_type[CURSEG_HOT_NODE]); 8302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, alloc_type[CURSEG_WARM_NODE]); 8402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, alloc_type[CURSEG_COLD_NODE]); 8502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_node_segno[0]); 8602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_node_segno[1]); 8702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_node_segno[2]); 8802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 8902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_node_blkoff[0]); 9002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_node_blkoff[1]); 9102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_node_blkoff[2]); 9202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 9302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 9402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, alloc_type[CURSEG_HOT_DATA]); 9502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, alloc_type[CURSEG_WARM_DATA]); 9602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, alloc_type[CURSEG_COLD_DATA]); 9702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_data_segno[0]); 9802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_data_segno[1]); 9902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_data_segno[2]); 10002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 10102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_data_blkoff[0]); 10202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_data_blkoff[1]); 10302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cur_data_blkoff[2]); 10402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 10502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, ckpt_flags); 10602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cp_pack_total_block_count); 10702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, cp_pack_start_sum); 10802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, valid_node_count); 10902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, valid_inode_count); 11002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, next_free_nid); 11102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, sit_ver_bitmap_bytesize); 11202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, nat_ver_bitmap_bytesize); 11302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, checksum_offset); 11402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u64(cp, elapsed_time); 11502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 11602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg D_DISP_u32(cp, sit_nat_version_bitmap[0]); 11702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("\n\n"); 11802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 11902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 12002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic void dbg_print_info_struct(struct f2fs_info *info) 12102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 12202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("\n"); 12302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("+--------------------------------------------------------+\n"); 12402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("| F2FS_INFO |\n"); 12502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("+--------------------------------------------------------+\n"); 12602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("blocks_per_segment: %"PRIu64, info->blocks_per_segment); 12702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("block_size: %d", info->block_size); 12802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("sit_bmp loc: %p", info->sit_bmp); 12902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("sit_bmp_size: %d", info->sit_bmp_size); 13002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("blocks_per_sit: %"PRIu64, info->blocks_per_sit); 13102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("sit_blocks loc: %p", info->sit_blocks); 13202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("sit_sums loc: %p", info->sit_sums); 13302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("cp_blkaddr: %"PRIu64, info->cp_blkaddr); 13402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("cp_valid_cp_blkaddr: %"PRIu64, info->cp_valid_cp_blkaddr); 13502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("sit_blkaddr: %"PRIu64, info->sit_blkaddr); 13602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("nat_blkaddr: %"PRIu64, info->nat_blkaddr); 13702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("ssa_blkaddr: %"PRIu64, info->ssa_blkaddr); 13802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("main_blkaddr: %"PRIu64, info->main_blkaddr); 13902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("total_user_used: %"PRIu64, info->total_user_used); 14002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("total_blocks: %"PRIu64, info->total_blocks); 14102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("\n\n"); 14202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 14302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 14402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 14502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg/* read blocks */ 14602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic int read_structure(int fd, unsigned long long start, void *buf, ssize_t len) 14702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 14802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg off64_t ret; 14902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 15002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg ret = lseek64(fd, start, SEEK_SET); 15102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ret < 0) { 15202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("failed to seek\n"); 15302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return ret; 15402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 15502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 15602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg ret = read(fd, buf, len); 15702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ret < 0) { 15802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("failed to read\n"); 15902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return ret; 16002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 16102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ret != len) { 16202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("failed to read all\n"); 16302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 16402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 16502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 16602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 16702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 16802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic int read_structure_blk(int fd, unsigned long long start_blk, void *buf, size_t len) 16902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 17002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return read_structure(fd, F2FS_BLKSIZE*start_blk, buf, F2FS_BLKSIZE * len); 17102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 17202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 17302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic int read_f2fs_sb(int fd, struct f2fs_super_block *sb) 17402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 17502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int rc; 17602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg rc = read_structure(fd, F2FS_SUPER_OFFSET, sb, sizeof(*sb)); 17702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (le32_to_cpu(sb->magic) != F2FS_SUPER_MAGIC) { 17802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Not a valid F2FS super block. Magic:%#08x != %#08x", 17902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg le32_to_cpu(sb->magic), F2FS_SUPER_MAGIC); 18002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 18102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 18202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 18302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 18402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 18502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergunsigned int get_f2fs_filesystem_size_sec(char *dev) 18602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 18702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int fd; 18802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if ((fd = open(dev, O_RDONLY)) < 0) { 18902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Cannot open device to get filesystem size "); 19002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 19102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 19202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_super_block sb; 19302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if(read_f2fs_sb(fd, &sb)) 19402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 19502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return (unsigned int)(le64_to_cpu(sb.block_count)*F2FS_BLKSIZE/DEFAULT_SECTOR_SIZE); 19602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 19702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 19802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic struct f2fs_checkpoint *validate_checkpoint(block_t cp_addr, 19902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned long long *version, int fd) 20002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 20102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned char *cp_block_1, *cp_block_2; 20202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_checkpoint *cp_block, *cp_ret; 20302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u64 cp1_version = 0, cp2_version = 0; 20402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 20502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp_block_1 = malloc(F2FS_BLKSIZE); 20602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!cp_block_1) 20702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return NULL; 20802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 20902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* Read the 1st cp block in this CP pack */ 21002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (read_structure_blk(fd, cp_addr, cp_block_1, 1)) 21102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto invalid_cp1; 21202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 21302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* get the version number */ 21402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp_block = (struct f2fs_checkpoint *)cp_block_1; 21502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 21602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp1_version = le64_to_cpu(cp_block->checkpoint_ver); 21702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 21802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp_block_2 = malloc(F2FS_BLKSIZE); 21902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!cp_block_2) { 22002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto invalid_cp1; 22102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 22202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* Read the 2nd cp block in this CP pack */ 22302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1; 22402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (read_structure_blk(fd, cp_addr, cp_block_2, 1)) { 22502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto invalid_cp2; 22602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 22702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 22802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp_block = (struct f2fs_checkpoint *)cp_block_2; 22902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 23002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp2_version = le64_to_cpu(cp_block->checkpoint_ver); 23102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 23202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (cp2_version == cp1_version) { 23302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg *version = cp2_version; 23402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(cp_block_2); 23502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return (struct f2fs_checkpoint *)cp_block_1; 23602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 23702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 23802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* There must be something wrong with this checkpoint */ 23902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberginvalid_cp2: 24002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(cp_block_2); 24102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberginvalid_cp1: 24202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(cp_block_1); 24302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return NULL; 24402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 24502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 24602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergint get_valid_checkpoint_info(int fd, struct f2fs_super_block *sb, struct f2fs_checkpoint **cp, struct f2fs_info *info) 24702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 24802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_checkpoint *cp_block; 24902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 25002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_checkpoint *cp1, *cp2, *cur_cp; 25102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int cur_cp_no; 25202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned long blk_size;// = 1<<le32_to_cpu(info->sb->log_blocksize); 25302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned long long cp1_version = 0, cp2_version = 0; 25402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned long long cp1_start_blk_no; 25502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned long long cp2_start_blk_no; 25602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u32 bmp_size; 25702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 25802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg blk_size = 1U<<le32_to_cpu(sb->log_blocksize); 25902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 26002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* 26102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg * Find valid cp by reading both packs and finding most recent one. 26202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg */ 26302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp1_start_blk_no = le32_to_cpu(sb->cp_blkaddr); 26402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp1 = validate_checkpoint(cp1_start_blk_no, &cp1_version, fd); 26502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 26602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* The second checkpoint pack should start at the next segment */ 26702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp2_start_blk_no = cp1_start_blk_no + (1 << le32_to_cpu(sb->log_blocks_per_seg)); 26802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cp2 = validate_checkpoint(cp2_start_blk_no, &cp2_version, fd); 26902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 27002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (cp1 && cp2) { 27102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ver_after(cp2_version, cp1_version)) { 27202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cur_cp = cp2; 27302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->cp_valid_cp_blkaddr = cp2_start_blk_no; 27402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(cp1); 27502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } else { 27602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cur_cp = cp1; 27702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->cp_valid_cp_blkaddr = cp1_start_blk_no; 27802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(cp2); 27902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 28002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } else if (cp1) { 28102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cur_cp = cp1; 28202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->cp_valid_cp_blkaddr = cp1_start_blk_no; 28302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } else if (cp2) { 28402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg cur_cp = cp2; 28502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->cp_valid_cp_blkaddr = cp2_start_blk_no; 28602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } else { 28702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto fail_no_cp; 28802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 28902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 29002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg *cp = cur_cp; 29102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 29202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 29302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 29402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergfail_no_cp: 29502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Valid Checkpoint not found!!"); 29602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -EINVAL; 29702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 29802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 29902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic int gather_sit_info(int fd, struct f2fs_info *info) 30002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 30102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u64 num_segments = (info->total_blocks - info->main_blkaddr 30202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg + info->blocks_per_segment - 1) / info->blocks_per_segment; 30302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u64 num_sit_blocks = (num_segments + SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK; 30402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u64 sit_block; 30502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 30602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_blocks = malloc(num_sit_blocks * sizeof(struct f2fs_sit_block)); 30702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!info->sit_blocks) 30802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 30902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 31002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg for(sit_block = 0; sit_block<num_sit_blocks; sit_block++) { 31102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg off64_t address = info->sit_blkaddr + sit_block; 31202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 31302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (f2fs_test_bit(sit_block, info->sit_bmp)) 31402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg address += info->blocks_per_sit; 31502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 31602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGD("Reading cache block starting at block %"PRIu64, address); 31702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (read_structure(fd, address * F2FS_BLKSIZE, &info->sit_blocks[sit_block], sizeof(struct f2fs_sit_block))) { 31802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Could not read sit block at block %"PRIu64, address); 31902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info->sit_blocks); 32002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 32102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 32202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 32302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 32402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 32502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 326aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenbergstatic inline int is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f) 327aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg{ 328aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags); 329aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg return !!(ckpt_flags & f); 330aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg} 331aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg 332aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenbergstatic inline u64 sum_blk_addr(struct f2fs_checkpoint *cp, struct f2fs_info *info, int base, int type) 333aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg{ 334aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg return info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_total_block_count) 335aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg - (base + 1) + type; 336aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg} 337aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg 33802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstatic int get_sit_summary(int fd, struct f2fs_info *info, struct f2fs_checkpoint *cp) 33902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 340aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg char buffer[F2FS_BLKSIZE]; 341aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg 34202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_sums = calloc(1, sizeof(struct f2fs_summary_block)); 34302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!info->sit_sums) 34402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 345aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg 346aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg /* CURSEG_COLD_DATA where the journaled SIT entries are. */ 347aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg if (is_set_ckpt_flags(cp, CP_COMPACT_SUM_FLAG)) { 348aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg if (read_structure_blk(fd, info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_start_sum), buffer, 1)) 349aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg return -1; 350aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg memcpy(&info->sit_sums->n_sits, &buffer[SUM_JOURNAL_SIZE], SUM_JOURNAL_SIZE); 351aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg } else { 352aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg u64 blk_addr; 353aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG)) 354aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg blk_addr = sum_blk_addr(cp, info, NR_CURSEG_TYPE, CURSEG_COLD_DATA); 355aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg else 356aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg blk_addr = sum_blk_addr(cp, info, NR_CURSEG_DATA_TYPE, CURSEG_COLD_DATA); 357aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg 358aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg if (read_structure_blk(fd, blk_addr, buffer, 1)) 359aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg return -1; 360aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg 361aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg memcpy(info->sit_sums, buffer, sizeof(struct f2fs_summary_block)); 362aff4a27b96454d6868a7a22974f560147a13188fDaniel Rosenberg } 36302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 36402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 36502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 36602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstruct f2fs_info *generate_f2fs_info(int fd) 36702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 36802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_super_block *sb = NULL; 36902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_checkpoint *cp = NULL; 37002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_info *info; 37102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 37202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info = calloc(1, sizeof(*info)); 37302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!info) { 37402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Out of memory!"); 37502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return NULL; 37602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 37702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 37802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg sb = malloc(sizeof(*sb)); 37902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if(!sb) { 38002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Out of memory!"); 38102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info); 38202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return NULL; 38302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 38402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (read_f2fs_sb(fd, sb)) { 38502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Failed to read superblock"); 38602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info); 38702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(sb); 38802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return NULL; 38902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 39002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg dbg_print_raw_sb_info(sb); 39102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 39202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->cp_blkaddr = le32_to_cpu(sb->cp_blkaddr); 39302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_blkaddr = le32_to_cpu(sb->sit_blkaddr); 39402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->nat_blkaddr = le32_to_cpu(sb->nat_blkaddr); 39502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->ssa_blkaddr = le32_to_cpu(sb->ssa_blkaddr); 39602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->main_blkaddr = le32_to_cpu(sb->main_blkaddr); 39702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->block_size = F2FS_BLKSIZE; 39802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->total_blocks = sb->block_count; 39902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->blocks_per_sit = (le32_to_cpu(sb->segment_count_sit) >> 1) << le32_to_cpu(sb->log_blocks_per_seg); 40002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->blocks_per_segment = 1U << le32_to_cpu(sb->log_blocks_per_seg); 40102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 40202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (get_valid_checkpoint_info(fd, sb, &cp, info)) 40302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto error; 40402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg dbg_print_raw_ckpt_struct(cp); 40502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 40602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->total_user_used = le32_to_cpu(cp->valid_block_count); 40702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 40802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u32 bmp_size = le32_to_cpu(cp->sit_ver_bitmap_bytesize); 40902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 41002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* get sit validity bitmap */ 41102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_bmp = malloc(bmp_size); 41202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if(!info->sit_bmp) { 41302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Out of memory!"); 41402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto error; 41502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 41602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 41702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_bmp_size = bmp_size; 41802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (read_structure(fd, info->cp_valid_cp_blkaddr * F2FS_BLKSIZE 41902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg + offsetof(struct f2fs_checkpoint, sit_nat_version_bitmap), 42002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_bmp, bmp_size)) { 42102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Error getting SIT validity bitmap"); 42202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto error; 42302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 42402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 42502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (gather_sit_info(fd , info)) { 42602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Error getting SIT information"); 42702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto error; 42802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 42902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (get_sit_summary(fd, info, cp)) { 43002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Error getting SIT entries in summary area"); 43102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg goto error; 43202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 43302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg dbg_print_info_struct(info); 43402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return info; 43502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergerror: 43602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(sb); 43702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(cp); 43802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free_f2fs_info(info); 43902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return NULL; 44002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 44102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 44202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergvoid free_f2fs_info(struct f2fs_info *info) 44302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 44402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (info) { 44502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info->sit_blocks); 44602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_blocks = NULL; 44702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 44802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info->sit_bmp); 44902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_bmp = NULL; 45002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 45102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info->sit_sums); 45202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg info->sit_sums = NULL; 45302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 45402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(info); 45502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 45602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 45702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergu64 get_num_blocks_used(struct f2fs_info *info) 45802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 45902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return info->main_blkaddr + info->total_user_used; 46002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 46102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 46202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergint f2fs_test_bit(unsigned int nr, const char *p) 46302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 46402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int mask; 46502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *addr = (char *)p; 46602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 46702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg addr += (nr >> 3); 46802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg mask = 1 << (7 - (nr & 0x07)); 46902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return (mask & *addr) != 0; 47002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 47102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 47202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#define segno_in_journal(sum, i) (sum->sit_j.entries[i].segno) 47302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 47402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg#define sit_in_journal(sum, i) (sum->sit_j.entries[i].se) 47502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 47602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergint run_on_used_blocks(u64 startblock, struct f2fs_info *info, int (*func)(u64 pos, void *data), void *data) { 47702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_sit_block sit_block_cache; 47802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_sit_entry * sit_entry, *sit_entry1, *sit_entry2; 47902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u64 sit_block_num_cur = 0, segnum=0, block_offset; 48002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg u64 block; 48102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg unsigned int used, found, started = 0, i; 48202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 48302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg for (block=startblock; block<info->total_blocks; block++) { 48402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* TODO: Save only relevant portions of metadata */ 48502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (block < info->main_blkaddr) { 48602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (func(block, data)) { 48702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGI("func error"); 48802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 48902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 49002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } else { 49102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* Main Section */ 49202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg segnum = (block - info->main_blkaddr)/info->blocks_per_segment; 49302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 49402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* check the SIT entries in the journal */ 49502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg found=0; 49602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg for(i = 0; i<SIT_JOURNAL_ENTRIES; i++) { 49702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (le32_to_cpu(segno_in_journal(info->sit_sums, i)) == segnum) { 49802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg sit_entry = &sit_in_journal(info->sit_sums, i); 49902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg found = 1; 50002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg break; 50102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 50202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 50302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 50402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg /* get SIT entry from SIT section */ 50502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!found) { 50602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg sit_block_num_cur = segnum/SIT_ENTRY_PER_BLOCK; 50702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg sit_entry = &info->sit_blocks[sit_block_num_cur].entries[segnum % SIT_ENTRY_PER_BLOCK]; 50802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 50902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 51002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg block_offset = (block - info->main_blkaddr) % info->blocks_per_segment; 51102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 51202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (block_offset == 0 && GET_SIT_VBLOCKS(sit_entry) == 0) { 51302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg block += info->blocks_per_segment; 51402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg continue; 51502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 51602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 51702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg used = f2fs_test_bit(block_offset, (char *)sit_entry->valid_map); 51802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if(used) 51902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (func(block, data)) 52002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 52102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 52202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 52302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 52402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 52502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 52602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergstruct privdata 52702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 52802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int count; 52902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int infd; 53002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int outfd; 53102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char* buf; 53202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *zbuf; 53302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int done; 53402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_info *info; 53502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg}; 53602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 53702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 53802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg/* 53902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg * This is a simple test program. It performs a block to block copy of a 54002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg * filesystem, replacing blocks identified as unused with 0's. 54102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg */ 54202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 54302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergint copy_used(u64 pos, void *data) 54402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 54502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct privdata *d = data; 54602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *buf; 54702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int pdone = (pos*100)/d->info->total_blocks; 54802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (pdone > d->done) { 54902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d->done = pdone; 55002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg printf("Done with %d percent\n", d->done); 55102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 55202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 55302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d->count++; 55402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg buf = d->buf; 55502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if(read_structure_blk(d->infd, (unsigned long long)pos, d->buf, 1)) { 55602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg printf("Error reading!!!\n"); 55702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 55802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 55902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 56002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg off64_t ret; 56102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg ret = lseek64(d->outfd, pos*F2FS_BLKSIZE, SEEK_SET); 56202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ret < 0) { 56302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("failed to seek\n"); 56402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return ret; 56502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 56602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 56702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg ret = write(d->outfd, d->buf, F2FS_BLKSIZE); 56802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ret < 0) { 56902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("failed to write\n"); 57002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return ret; 57102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 57202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (ret != F2FS_BLKSIZE) { 57302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("failed to read all\n"); 57402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 57502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 57602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 57702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 57802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 57902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenbergint main(int argc, char **argv) 58002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg{ 58102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (argc != 3) 58202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg printf("Usage: %s fs_file_in fs_file_out\n", argv[0]); 58302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *in = argv[1]; 58402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *out = argv[2]; 58502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int infd, outfd; 58602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 58702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if ((infd = open(in, O_RDONLY)) < 0) { 58802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Cannot open device"); 58902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 59002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 59102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if ((outfd = open(out, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR)) < 0) { 59202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg SLOGE("Cannot open output"); 59302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 59402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 59502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg 59602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct privdata d; 59702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.infd = infd; 59802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.outfd = outfd; 59902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.count = 0; 60002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg struct f2fs_info *info = generate_f2fs_info(infd); 60102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg if (!info) { 60202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg printf("Failed to generate info!"); 60302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return -1; 60402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg } 60502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *buf = malloc(F2FS_BLKSIZE); 60602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg char *zbuf = calloc(1, F2FS_BLKSIZE); 60702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.buf = buf; 60802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.zbuf = zbuf; 60902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.done = 0; 61002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg d.info = info; 61102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg int expected_count = get_num_blocks_used(info); 61202e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg run_on_used_blocks(0, info, ©_used, &d); 61302e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg printf("Copied %d blocks. Expected to copy %d\n", d.count, expected_count); 61402e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg ftruncate64(outfd, info->total_blocks * F2FS_BLKSIZE); 61502e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free_f2fs_info(info); 61602e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(buf); 61702e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg free(zbuf); 61802e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg close(infd); 61902e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg close(outfd); 62002e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg return 0; 62102e662508d7c6b96df94154b2fdf9c8f2c348690Daniel Rosenberg} 622