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