1 /** 2 * dump.c 3 * 4 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 #include "fsck.h" 12 13 #define BUF_SZ 80 14 15 const char *seg_type_name[SEG_TYPE_MAX] = { 16 "SEG_TYPE_DATA", 17 "SEG_TYPE_CUR_DATA", 18 "SEG_TYPE_NODE", 19 "SEG_TYPE_CUR_NODE", 20 }; 21 22 void sit_dump(struct f2fs_sb_info *sbi, int start_sit, int end_sit) 23 { 24 struct seg_entry *se; 25 int segno; 26 char buf[BUF_SZ]; 27 u32 free_segs = 0;; 28 u64 valid_blocks = 0; 29 int ret; 30 int fd; 31 32 fd = open("dump_sit", O_CREAT|O_WRONLY|O_TRUNC, 0666); 33 ASSERT(fd >= 0); 34 35 for (segno = start_sit; segno < end_sit; segno++) { 36 se = get_seg_entry(sbi, segno); 37 38 memset(buf, 0, BUF_SZ); 39 snprintf(buf, BUF_SZ, "%5d %8d\n", segno, se->valid_blocks); 40 41 ret = write(fd, buf, strlen(buf)); 42 ASSERT(ret >= 0); 43 44 DBG(4, "SIT[0x%3x] : 0x%x\n", segno, se->valid_blocks); 45 if (se->valid_blocks == 0x0) { 46 free_segs++; 47 } else { 48 ASSERT(se->valid_blocks <= 512); 49 valid_blocks += se->valid_blocks; 50 } 51 } 52 53 memset(buf, 0, BUF_SZ); 54 snprintf(buf, BUF_SZ, "valid_segs:%d\t free_segs:%d\n", 55 SM_I(sbi)->main_segments - free_segs, free_segs); 56 ret = write(fd, buf, strlen(buf)); 57 ASSERT(ret >= 0); 58 59 close(fd); 60 DBG(1, "Blocks [0x%lx] Free Segs [0x%x]\n", valid_blocks, free_segs); 61 } 62 63 void ssa_dump(struct f2fs_sb_info *sbi, int start_ssa, int end_ssa) 64 { 65 struct f2fs_summary_block sum_blk; 66 char buf[BUF_SZ]; 67 int segno, i, ret; 68 int fd; 69 70 fd = open("dump_ssa", O_CREAT|O_WRONLY|O_TRUNC, 0666); 71 ASSERT(fd >= 0); 72 73 snprintf(buf, BUF_SZ, "Note: dump.f2fs -b blkaddr = 0x%x + segno * " 74 " 0x200 + offset\n", 75 sbi->sm_info->main_blkaddr); 76 ret = write(fd, buf, strlen(buf)); 77 ASSERT(ret >= 0); 78 79 for (segno = start_ssa; segno < end_ssa; segno++) { 80 ret = get_sum_block(sbi, segno, &sum_blk); 81 82 memset(buf, 0, BUF_SZ); 83 switch (ret) { 84 case SEG_TYPE_CUR_NODE: 85 snprintf(buf, BUF_SZ, "\n\nsegno: %x, Current Node\n", segno); 86 break; 87 case SEG_TYPE_CUR_DATA: 88 snprintf(buf, BUF_SZ, "\n\nsegno: %x, Current Data\n", segno); 89 break; 90 case SEG_TYPE_NODE: 91 snprintf(buf, BUF_SZ, "\n\nsegno: %x, Node\n", segno); 92 break; 93 case SEG_TYPE_DATA: 94 snprintf(buf, BUF_SZ, "\n\nsegno: %x, Data\n", segno); 95 break; 96 } 97 ret = write(fd, buf, strlen(buf)); 98 ASSERT(ret >= 0); 99 100 for (i = 0; i < ENTRIES_IN_SUM; i++) { 101 memset(buf, 0, BUF_SZ); 102 if (i % 10 == 0) { 103 buf[0] = '\n'; 104 ret = write(fd, buf, strlen(buf)); 105 ASSERT(ret >= 0); 106 } 107 snprintf(buf, BUF_SZ, "[%3d: %6x]", i, 108 le32_to_cpu(sum_blk.entries[i].nid)); 109 ret = write(fd, buf, strlen(buf)); 110 ASSERT(ret >= 0); 111 } 112 } 113 close(fd); 114 } 115 116 int dump_node(struct f2fs_sb_info *sbi, nid_t nid) 117 { 118 struct node_info ni; 119 struct f2fs_node *node_blk; 120 int ret; 121 122 ret = get_node_info(sbi, nid, &ni); 123 ASSERT(ret >= 0); 124 125 node_blk = calloc(BLOCK_SZ, 1); 126 dev_read_block(node_blk, ni.blk_addr); 127 128 DBG(1, "Node ID [0x%x]\n", nid); 129 DBG(1, "nat_entry.block_addr [0x%x]\n", ni.blk_addr); 130 DBG(1, "nat_entry.version [0x%x]\n", ni.version); 131 DBG(1, "nat_entry.ino [0x%x]\n", ni.ino); 132 133 if (ni.blk_addr == 0x0) { 134 MSG(0, "Invalid nat entry\n\n"); 135 } 136 137 DBG(1, "node_blk.footer.ino [0x%x]\n", le32_to_cpu(node_blk->footer.ino)); 138 DBG(1, "node_blk.footer.nid [0x%x]\n", le32_to_cpu(node_blk->footer.nid)); 139 140 if (le32_to_cpu(node_blk->footer.ino) == ni.ino && 141 le32_to_cpu(node_blk->footer.nid) == ni.nid) { 142 print_node_info(node_blk); 143 } else { 144 MSG(0, "Invalid node block\n\n"); 145 } 146 147 free(node_blk); 148 return 0; 149 } 150 151 int dump_inode_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr) 152 { 153 nid_t ino, nid; 154 int type, ret; 155 struct f2fs_summary sum_entry; 156 struct node_info ni; 157 struct f2fs_node *node_blk; 158 159 type = get_sum_entry(sbi, blk_addr, &sum_entry); 160 nid = le32_to_cpu(sum_entry.nid); 161 162 ret = get_node_info(sbi, nid, &ni); 163 ASSERT(ret >= 0); 164 165 DBG(1, "Note: blkaddr = main_blkaddr + segno * 512 + offset\n"); 166 DBG(1, "Block_addr [0x%x]\n", blk_addr); 167 DBG(1, " - Segno [0x%x]\n", GET_SEGNO(sbi, blk_addr)); 168 DBG(1, " - Offset [0x%x]\n", OFFSET_IN_SEG(sbi, blk_addr)); 169 DBG(1, "SUM.nid [0x%x]\n", nid); 170 DBG(1, "SUM.type [%s]\n", seg_type_name[type]); 171 DBG(1, "SUM.version [%d]\n", sum_entry.version); 172 DBG(1, "SUM.ofs_in_node [%d]\n", sum_entry.ofs_in_node); 173 DBG(1, "NAT.blkaddr [0x%x]\n", ni.blk_addr); 174 DBG(1, "NAT.ino [0x%x]\n", ni.ino); 175 176 node_blk = calloc(BLOCK_SZ, 1); 177 178 read_node_blk: 179 dev_read_block(node_blk, blk_addr); 180 181 ino = le32_to_cpu(node_blk->footer.ino); 182 nid = le32_to_cpu(node_blk->footer.nid); 183 184 if (ino == nid) { 185 print_node_info(node_blk); 186 } else { 187 ret = get_node_info(sbi, ino, &ni); 188 goto read_node_blk; 189 } 190 191 free(node_blk); 192 return ino; 193 } 194