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