blob: 1ed505029cc473cb3b5a1e59c8a229d8fc821cc7 [file] [log] [blame]
Changman Lee7f35b542013-07-04 17:11:32 +09001/**
2 * mount.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
13void print_inode_info(struct f2fs_inode *inode)
14{
15 int i = 0;
16 int namelen = le32_to_cpu(inode->i_namelen);
17
18 DISP_u32(inode, i_mode);
19 DISP_u32(inode, i_uid);
20 DISP_u32(inode, i_gid);
21 DISP_u32(inode, i_links);
22 DISP_u64(inode, i_size);
23 DISP_u64(inode, i_blocks);
24
25 DISP_u64(inode, i_atime);
26 DISP_u32(inode, i_atime_nsec);
27 DISP_u64(inode, i_ctime);
28 DISP_u32(inode, i_ctime_nsec);
29 DISP_u64(inode, i_mtime);
30 DISP_u32(inode, i_mtime_nsec);
31
32 DISP_u32(inode, i_generation);
33 DISP_u32(inode, i_current_depth);
34 DISP_u32(inode, i_xattr_nid);
35 DISP_u32(inode, i_flags);
36 DISP_u32(inode, i_pino);
37
38 if (namelen) {
39 DISP_u32(inode, i_namelen);
40 inode->i_name[namelen] = '\0';
41 DISP_utf(inode, i_name);
42 }
43
44 printf("i_ext: fofs:%x blkaddr:%x len:%x\n",
45 inode->i_ext.fofs,
46 inode->i_ext.blk_addr,
47 inode->i_ext.len);
48
49 DISP_u32(inode, i_addr[0]); /* Pointers to data blocks */
50 DISP_u32(inode, i_addr[1]); /* Pointers to data blocks */
51 DISP_u32(inode, i_addr[2]); /* Pointers to data blocks */
52 DISP_u32(inode, i_addr[3]); /* Pointers to data blocks */
53
54 for (i = 4; i < ADDRS_PER_INODE; i++) {
55 if (inode->i_addr[i] != 0x0) {
56 printf("i_addr[0x%x] points data block\r\t\t\t\t[0x%4x]\n",
57 i, inode->i_addr[i]);
58 break;
59 }
60 }
61
62 DISP_u32(inode, i_nid[0]); /* direct */
63 DISP_u32(inode, i_nid[1]); /* direct */
64 DISP_u32(inode, i_nid[2]); /* indirect */
65 DISP_u32(inode, i_nid[3]); /* indirect */
66 DISP_u32(inode, i_nid[4]); /* double indirect */
67
68 printf("\n");
69}
70
71void print_node_info(struct f2fs_node *node_block)
72{
73 nid_t ino = le32_to_cpu(node_block->footer.ino);
74 nid_t nid = le32_to_cpu(node_block->footer.nid);
75 /* Is this inode? */
76 if (ino == nid) {
77 DBG(0, "Node ID [0x%x:%u] is inode\n", nid, nid);
78 print_inode_info(&node_block->i);
79 } else {
80 DBG(0, "Node ID [0x%x:%u] is direct node or indirect node.\n", nid, nid);
81 }
82}
83
84void print_raw_sb_info(struct f2fs_sb_info *sbi)
85{
86 struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
87 printf("\n");
88 printf("+--------------------------------------------------------+\n");
89 printf("| Super block |\n");
90 printf("+--------------------------------------------------------+\n");
91
92 DISP_u32(sb, magic);
93 DISP_u32(sb, major_ver);
94 DISP_u32(sb, minor_ver);
95 DISP_u32(sb, log_sectorsize);
96 DISP_u32(sb, log_sectors_per_block);
97
98 DISP_u32(sb, log_blocksize);
99 DISP_u32(sb, log_blocks_per_seg);
100 DISP_u32(sb, segs_per_sec);
101 DISP_u32(sb, secs_per_zone);
102 DISP_u32(sb, checksum_offset);
103 DISP_u64(sb, block_count);
104
105 DISP_u32(sb, section_count);
106 DISP_u32(sb, segment_count);
107 DISP_u32(sb, segment_count_ckpt);
108 DISP_u32(sb, segment_count_sit);
109 DISP_u32(sb, segment_count_nat);
110
111 DISP_u32(sb, segment_count_ssa);
112 DISP_u32(sb, segment_count_main);
113 DISP_u32(sb, segment0_blkaddr);
114
115 DISP_u32(sb, cp_blkaddr);
116 DISP_u32(sb, sit_blkaddr);
117 DISP_u32(sb, nat_blkaddr);
118 DISP_u32(sb, ssa_blkaddr);
119 DISP_u32(sb, main_blkaddr);
120
121 DISP_u32(sb, root_ino);
122 DISP_u32(sb, node_ino);
123 DISP_u32(sb, meta_ino);
124 printf("\n");
125}
126
127void print_ckpt_info(struct f2fs_sb_info *sbi)
128{
129 struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
130
131 printf("\n");
132 printf("+--------------------------------------------------------+\n");
133 printf("| Checkpoint |\n");
134 printf("+--------------------------------------------------------+\n");
135
136 DISP_u64(cp, checkpoint_ver);
137 DISP_u64(cp, user_block_count);
138 DISP_u64(cp, valid_block_count);
139 DISP_u32(cp, rsvd_segment_count);
140 DISP_u32(cp, overprov_segment_count);
141 DISP_u32(cp, free_segment_count);
142
143 DISP_u32(cp, alloc_type[CURSEG_HOT_NODE]);
144 DISP_u32(cp, alloc_type[CURSEG_WARM_NODE]);
145 DISP_u32(cp, alloc_type[CURSEG_COLD_NODE]);
146 DISP_u32(cp, cur_node_segno[0]);
147 DISP_u32(cp, cur_node_segno[1]);
148 DISP_u32(cp, cur_node_segno[2]);
149
150 DISP_u32(cp, cur_node_blkoff[0]);
151 DISP_u32(cp, cur_node_blkoff[1]);
152 DISP_u32(cp, cur_node_blkoff[2]);
153
154
155 DISP_u32(cp, alloc_type[CURSEG_HOT_DATA]);
156 DISP_u32(cp, alloc_type[CURSEG_WARM_DATA]);
157 DISP_u32(cp, alloc_type[CURSEG_COLD_DATA]);
158 DISP_u32(cp, cur_data_segno[0]);
159 DISP_u32(cp, cur_data_segno[1]);
160 DISP_u32(cp, cur_data_segno[2]);
161
162 DISP_u32(cp, cur_data_blkoff[0]);
163 DISP_u32(cp, cur_data_blkoff[1]);
164 DISP_u32(cp, cur_data_blkoff[2]);
165
166 DISP_u32(cp, ckpt_flags);
167 DISP_u32(cp, cp_pack_total_block_count);
168 DISP_u32(cp, cp_pack_start_sum);
169 DISP_u32(cp, valid_node_count);
170 DISP_u32(cp, valid_inode_count);
171 DISP_u32(cp, next_free_nid);
172 DISP_u32(cp, sit_ver_bitmap_bytesize);
173 DISP_u32(cp, nat_ver_bitmap_bytesize);
174 DISP_u32(cp, checksum_offset);
175 DISP_u64(cp, elapsed_time);
176
177 DISP_u32(cp, sit_nat_version_bitmap[0]);
178 printf("\n\n");
179}
180
181int sanity_check_raw_super(struct f2fs_super_block *raw_super)
182{
183 unsigned int blocksize;
184
185 if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) {
186 return -1;
187 }
188
189 if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) {
190 return -1;
191 }
192
193 blocksize = 1 << le32_to_cpu(raw_super->log_blocksize);
194 if (F2FS_BLKSIZE != blocksize) {
195 return -1;
196 }
197
198 if (F2FS_LOG_SECTOR_SIZE != le32_to_cpu(raw_super->log_sectorsize)) {
199 return -1;
200 }
201
202 if (F2FS_LOG_SECTORS_PER_BLOCK != le32_to_cpu(raw_super->log_sectors_per_block)) {
203 return -1;
204 }
205
206 return 0;
207}
208
209int validate_super_block(struct f2fs_sb_info *sbi, int block)
210{
211 u64 offset = (block + 1) * F2FS_SUPER_OFFSET;
212 sbi->raw_super = malloc(sizeof(struct f2fs_super_block));
213
214 if (dev_read(sbi->raw_super, offset, sizeof(struct f2fs_super_block)))
215 return -1;
216
217 if (!sanity_check_raw_super(sbi->raw_super))
218 return 0;
219
220 free(sbi->raw_super);
221 MSG(0, "\tCan't find a valid F2FS filesystem in %d superblock\n", block);
222
223 return -EINVAL;
224}
225
226int init_sb_info(struct f2fs_sb_info *sbi)
227{
228 struct f2fs_super_block *raw_super = sbi->raw_super;
229
230 sbi->log_sectors_per_block =
231 le32_to_cpu(raw_super->log_sectors_per_block);
232 sbi->log_blocksize = le32_to_cpu(raw_super->log_blocksize);
233 sbi->blocksize = 1 << sbi->log_blocksize;
234 sbi->log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
235 sbi->blocks_per_seg = 1 << sbi->log_blocks_per_seg;
236 sbi->segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
237 sbi->secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
238 sbi->total_sections = le32_to_cpu(raw_super->section_count);
239 sbi->total_node_count =
240 (le32_to_cpu(raw_super->segment_count_nat) / 2)
241 * sbi->blocks_per_seg * NAT_ENTRY_PER_BLOCK;
242 sbi->root_ino_num = le32_to_cpu(raw_super->root_ino);
243 sbi->node_ino_num = le32_to_cpu(raw_super->node_ino);
244 sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino);
245 sbi->cur_victim_sec = NULL_SEGNO;
246 return 0;
247}
248
249void *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr, unsigned long long *version)
250{
251 void *cp_page_1, *cp_page_2;
252 struct f2fs_checkpoint *cp_block;
253 unsigned long blk_size = sbi->blocksize;
254 unsigned long long cur_version = 0, pre_version = 0;
255 unsigned int crc = 0;
256 size_t crc_offset;
257
258 /* Read the 1st cp block in this CP pack */
259 cp_page_1 = malloc(PAGE_SIZE);
260 if (dev_read_block(cp_page_1, cp_addr) < 0)
261 return NULL;
262
263 cp_block = (struct f2fs_checkpoint *)cp_page_1;
264 crc_offset = le32_to_cpu(cp_block->checksum_offset);
265 if (crc_offset >= blk_size)
266 goto invalid_cp1;
267
268 crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
269 if (f2fs_crc_valid(crc, cp_block, crc_offset))
270 goto invalid_cp1;
271
272 pre_version = le64_to_cpu(cp_block->checkpoint_ver);
273
274 /* Read the 2nd cp block in this CP pack */
275 cp_page_2 = malloc(PAGE_SIZE);
276 cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
277 if (dev_read_block(cp_page_2, cp_addr) < 0)
278 goto invalid_cp2;
279
280 cp_block = (struct f2fs_checkpoint *)cp_page_2;
281 crc_offset = le32_to_cpu(cp_block->checksum_offset);
282 if (crc_offset >= blk_size)
283 goto invalid_cp2;
284
285 crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
286 if (f2fs_crc_valid(crc, cp_block, crc_offset))
287 goto invalid_cp1;
288
289 cur_version = le64_to_cpu(cp_block->checkpoint_ver);
290
291 if (cur_version == pre_version) {
292 *version = cur_version;
293 free(cp_page_2);
294 return cp_page_1;
295 }
296
297invalid_cp2:
298 free(cp_page_2);
299invalid_cp1:
300 free(cp_page_1);
301 return NULL;
302}
303
304int get_valid_checkpoint(struct f2fs_sb_info *sbi)
305{
306 struct f2fs_super_block *raw_sb = sbi->raw_super;
307 void *cp1, *cp2, *cur_page;
308 unsigned long blk_size = sbi->blocksize;
309 unsigned long long cp1_version = 0, cp2_version = 0;
310 unsigned long long cp_start_blk_no;
311
312 sbi->ckpt = malloc(blk_size);
313 if (!sbi->ckpt)
314 return -ENOMEM;
315 /*
316 * Finding out valid cp block involves read both
317 * sets( cp pack1 and cp pack 2)
318 */
319 cp_start_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
320 cp1 = validate_checkpoint(sbi, cp_start_blk_no, &cp1_version);
321
322 /* The second checkpoint pack should start at the next segment */
323 cp_start_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg);
324 cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version);
325
326 if (cp1 && cp2) {
327 if (ver_after(cp2_version, cp1_version))
328 cur_page = cp2;
329 else
330 cur_page = cp1;
331 } else if (cp1) {
332 cur_page = cp1;
333 } else if (cp2) {
334 cur_page = cp2;
335 } else {
336 free(cp1);
337 free(cp2);
338 goto fail_no_cp;
339 }
340
341 memcpy(sbi->ckpt, cur_page, blk_size);
342
343 free(cp1);
344 free(cp2);
345 return 0;
346
347fail_no_cp:
348 free(sbi->ckpt);
349 return -EINVAL;
350}
351
352int sanity_check_ckpt(struct f2fs_sb_info *sbi)
353{
354 unsigned int total, fsmeta;
355 struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
356 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
357
358 total = le32_to_cpu(raw_super->segment_count);
359 fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
360 fsmeta += le32_to_cpu(raw_super->segment_count_sit);
361 fsmeta += le32_to_cpu(raw_super->segment_count_nat);
362 fsmeta += le32_to_cpu(ckpt->rsvd_segment_count);
363 fsmeta += le32_to_cpu(raw_super->segment_count_ssa);
364
365 if (fsmeta >= total)
366 return 1;
367
368 return 0;
369}
370
371int init_node_manager(struct f2fs_sb_info *sbi)
372{
373 struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi);
374 struct f2fs_nm_info *nm_i = NM_I(sbi);
375 unsigned char *version_bitmap;
376 unsigned int nat_segs, nat_blocks;
377
378 nm_i->nat_blkaddr = le32_to_cpu(sb_raw->nat_blkaddr);
379
380 /* segment_count_nat includes pair segment so divide to 2. */
381 nat_segs = le32_to_cpu(sb_raw->segment_count_nat) >> 1;
382 nat_blocks = nat_segs << le32_to_cpu(sb_raw->log_blocks_per_seg);
383 nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks;
384 nm_i->fcnt = 0;
385 nm_i->nat_cnt = 0;
386 nm_i->init_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid);
387 nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid);
388
389 nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP);
390
391 nm_i->nat_bitmap = malloc(nm_i->bitmap_size);
392 if (!nm_i->nat_bitmap)
393 return -ENOMEM;
394 version_bitmap = __bitmap_ptr(sbi, NAT_BITMAP);
395 if (!version_bitmap)
396 return -EFAULT;
397
398 /* copy version bitmap */
399 memcpy(nm_i->nat_bitmap, version_bitmap, nm_i->bitmap_size);
400 return 0;
401}
402
403int build_node_manager(struct f2fs_sb_info *sbi)
404{
405 int err;
406 sbi->nm_info = malloc(sizeof(struct f2fs_nm_info));
407 if (!sbi->nm_info)
408 return -ENOMEM;
409
410 err = init_node_manager(sbi);
411 if (err)
412 return err;
413
414 return 0;
415}
416
417int build_sit_info(struct f2fs_sb_info *sbi)
418{
419 struct f2fs_super_block *raw_sb = F2FS_RAW_SUPER(sbi);
420 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
421 struct sit_info *sit_i;
422 unsigned int sit_segs, start;
423 char *src_bitmap, *dst_bitmap;
424 unsigned int bitmap_size;
425
426 sit_i = malloc(sizeof(struct sit_info));
427 if (!sit_i)
428 return -ENOMEM;
429
430 SM_I(sbi)->sit_info = sit_i;
431
432 sit_i->sentries = calloc(TOTAL_SEGS(sbi) * sizeof(struct seg_entry), 1);
433
434 for (start = 0; start < TOTAL_SEGS(sbi); start++) {
435 sit_i->sentries[start].cur_valid_map
436 = calloc(SIT_VBLOCK_MAP_SIZE, 1);
437 sit_i->sentries[start].ckpt_valid_map
438 = calloc(SIT_VBLOCK_MAP_SIZE, 1);
439 if (!sit_i->sentries[start].cur_valid_map
440 || !sit_i->sentries[start].ckpt_valid_map)
441 return -ENOMEM;
442 }
443
444 sit_segs = le32_to_cpu(raw_sb->segment_count_sit) >> 1;
445 bitmap_size = __bitmap_size(sbi, SIT_BITMAP);
446 src_bitmap = __bitmap_ptr(sbi, SIT_BITMAP);
447
448 dst_bitmap = malloc(bitmap_size);
449 memcpy(dst_bitmap, src_bitmap, bitmap_size);
450
451 sit_i->sit_base_addr = le32_to_cpu(raw_sb->sit_blkaddr);
452 sit_i->sit_blocks = sit_segs << sbi->log_blocks_per_seg;
453 sit_i->written_valid_blocks = le64_to_cpu(ckpt->valid_block_count);
454 sit_i->sit_bitmap = dst_bitmap;
455 sit_i->bitmap_size = bitmap_size;
456 sit_i->dirty_sentries = 0;
457 sit_i->sents_per_block = SIT_ENTRY_PER_BLOCK;
458 sit_i->elapsed_time = le64_to_cpu(ckpt->elapsed_time);
459 return 0;
460}
461
462void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
463{
464 struct curseg_info *curseg = CURSEG_I(sbi, type);
465
466 curseg->segno = curseg->next_segno;
467 curseg->zone = GET_ZONENO_FROM_SEGNO(sbi, curseg->segno);
468 curseg->next_blkoff = 0;
469 curseg->next_segno = NULL_SEGNO;
470
471}
472
473int read_compacted_summaries(struct f2fs_sb_info *sbi)
474{
475 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
476 struct curseg_info *curseg;
477 block_t start;
478 char *kaddr;
479 unsigned int i, j, offset;
480
481 start = start_sum_block(sbi);
482
483 kaddr = (char *)malloc(PAGE_SIZE);
484 dev_read_block(kaddr, start++);
485
486 curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
487 memcpy(&curseg->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE);
488
489 curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
490 memcpy(&curseg->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE, SUM_JOURNAL_SIZE);
491
492 offset = 2 * SUM_JOURNAL_SIZE;
493 for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
494 unsigned short blk_off;
495 unsigned int segno;
496
497 curseg = CURSEG_I(sbi, i);
498 segno = le32_to_cpu(ckpt->cur_data_segno[i]);
499 blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
500 curseg->next_segno = segno;
501 reset_curseg(sbi, i, 0);
502 curseg->alloc_type = ckpt->alloc_type[i];
503 curseg->next_blkoff = blk_off;
504
505 if (curseg->alloc_type == SSR)
506 blk_off = sbi->blocks_per_seg;
507
508 for (j = 0; j < blk_off; j++) {
509 struct f2fs_summary *s;
510 s = (struct f2fs_summary *)(kaddr + offset);
511 curseg->sum_blk->entries[j] = *s;
512 offset += SUMMARY_SIZE;
513 if (offset + SUMMARY_SIZE <= PAGE_CACHE_SIZE - SUM_FOOTER_SIZE)
514 continue;
515 memset(kaddr, 0, PAGE_SIZE);
516 dev_read_block(kaddr, start++);
517 offset = 0;
518 }
519 }
520
521 free(kaddr);
522 return 0;
523}
524
525int restore_node_summary(struct f2fs_sb_info *sbi,
526 unsigned int segno, struct f2fs_summary_block *sum_blk)
527{
528 struct f2fs_node *node_blk;
529 struct f2fs_summary *sum_entry;
530 void *page;
531 block_t addr;
532 int i;
533
534 page = malloc(PAGE_SIZE);
535 if (!page)
536 return -ENOMEM;
537
538 /* scan the node segment */
539 addr = START_BLOCK(sbi, segno);
540 sum_entry = &sum_blk->entries[0];
541
542 for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
543 if (dev_read_block(page, addr))
544 goto out;
545
546 node_blk = (struct f2fs_node *)page;
547 sum_entry->nid = node_blk->footer.nid;
548 /* do not change original value */
549#if 0
550 sum_entry->version = 0;
551 sum_entry->ofs_in_node = 0;
552#endif
553 addr++;
554
555 }
556out:
557 free(page);
558 return 0;
559}
560
561int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
562{
563 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
564 struct f2fs_summary_block *sum_blk;
565 struct curseg_info *curseg;
566 unsigned short blk_off;
567 unsigned int segno = 0;
568 block_t blk_addr = 0;
569
570 if (IS_DATASEG(type)) {
571 segno = le32_to_cpu(ckpt->cur_data_segno[type]);
572 blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - CURSEG_HOT_DATA]);
573
574 if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
575 blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
576 else
577 blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
578 } else {
579 segno = le32_to_cpu(ckpt->cur_node_segno[type - CURSEG_HOT_NODE]);
580 blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - CURSEG_HOT_NODE]);
581
582 if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
583 blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, type - CURSEG_HOT_NODE);
584 else
585 blk_addr = GET_SUM_BLKADDR(sbi, segno);
586 }
587
588 sum_blk = (struct f2fs_summary_block *)malloc(PAGE_SIZE);
589 dev_read_block(sum_blk, blk_addr);
590
591 if (IS_NODESEG(type)) {
592 if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) {
593 struct f2fs_summary *sum_entry = &sum_blk->entries[0];
594 int i;
595 for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
596 /* do not change original value */
597#if 0
598 sum_entry->version = 0;
599 sum_entry->ofs_in_node = 0;
600#endif
601 }
602 } else {
603 if (restore_node_summary(sbi, segno, sum_blk)) {
604 free(sum_blk);
605 return -EINVAL;
606 }
607 }
608 }
609
610 curseg = CURSEG_I(sbi, type);
611 memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
612 curseg->next_segno = segno;
613 reset_curseg(sbi, type, 0);
614 curseg->alloc_type = ckpt->alloc_type[type];
615 curseg->next_blkoff = blk_off;
616 free(sum_blk);
617
618 return 0;
619}
620
621int restore_curseg_summaries(struct f2fs_sb_info *sbi)
622{
623 int type = CURSEG_HOT_DATA;
624
625 if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) {
626 if (read_compacted_summaries(sbi))
627 return -EINVAL;
628 type = CURSEG_HOT_NODE;
629 }
630
631 for (; type <= CURSEG_COLD_NODE; type++) {
632 if (read_normal_summaries(sbi, type))
633 return -EINVAL;
634 }
635 return 0;
636}
637
638int build_curseg(struct f2fs_sb_info *sbi)
639{
640 struct curseg_info *array;
641 int i;
642
643 array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
644
645 SM_I(sbi)->curseg_array = array;
646
647 for (i = 0; i < NR_CURSEG_TYPE; i++) {
648 array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
649 if (!array[i].sum_blk)
650 return -ENOMEM;
651 array[i].segno = NULL_SEGNO;
652 array[i].next_blkoff = 0;
653 }
654 return restore_curseg_summaries(sbi);
655}
656
657inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
658{
659 unsigned int end_segno = SM_I(sbi)->segment_count - 1;
660 ASSERT(segno <= end_segno);
661}
662
663struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi, unsigned int segno)
664{
665 struct sit_info *sit_i = SIT_I(sbi);
666 unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
667 block_t blk_addr = sit_i->sit_base_addr + offset;
668 struct f2fs_sit_block *sit_blk = calloc(BLOCK_SZ, 1);
669
670 check_seg_range(sbi, segno);
671
672 /* calculate sit block address */
673 if (f2fs_test_bit(offset, sit_i->sit_bitmap))
674 blk_addr += sit_i->sit_blocks;
675
676 dev_read_block(sit_blk, blk_addr);
677
678 return sit_blk;
679}
680
681void check_block_count(struct f2fs_sb_info *sbi,
682 int segno, struct f2fs_sit_entry *raw_sit)
683{
684 struct f2fs_sm_info *sm_info = SM_I(sbi);
685 unsigned int end_segno = sm_info->segment_count - 1;
686 int valid_blocks = 0;
687 int i;
688
689 /* check segment usage */
690 ASSERT(GET_SIT_VBLOCKS(raw_sit) <= sbi->blocks_per_seg);
691
692 /* check boundary of a given segment number */
693 ASSERT(segno <= end_segno);
694
695 /* check bitmap with valid block count */
696 for (i = 0; i < sbi->blocks_per_seg; i++)
697 if (f2fs_test_bit(i, (char *)raw_sit->valid_map))
698 valid_blocks++;
699 ASSERT(GET_SIT_VBLOCKS(raw_sit) == valid_blocks);
700}
701
702void seg_info_from_raw_sit(struct seg_entry *se,
703 struct f2fs_sit_entry *raw_sit)
704{
705 se->valid_blocks = GET_SIT_VBLOCKS(raw_sit);
706 se->ckpt_valid_blocks = GET_SIT_VBLOCKS(raw_sit);
707 memcpy(se->cur_valid_map, raw_sit->valid_map, SIT_VBLOCK_MAP_SIZE);
708 memcpy(se->ckpt_valid_map, raw_sit->valid_map, SIT_VBLOCK_MAP_SIZE);
709 se->type = GET_SIT_TYPE(raw_sit);
710 se->mtime = le64_to_cpu(raw_sit->mtime);
711}
712
713struct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi,
714 unsigned int segno)
715{
716 struct sit_info *sit_i = SIT_I(sbi);
717 return &sit_i->sentries[segno];
718}
719
720int get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summary_block *sum_blk)
721{
722 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
723 struct curseg_info *curseg;
724 int type, ret;
725 u64 ssa_blk;
726
727 ssa_blk = GET_SUM_BLKADDR(sbi, segno);
728 for (type = 0; type < NR_CURSEG_NODE_TYPE; type++) {
729 if (segno == ckpt->cur_node_segno[type]) {
730 curseg = CURSEG_I(sbi, type);
731 memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
732 return SEG_TYPE_CUR_NODE; /* current node seg was not stored */
733 }
734 }
735
736 for (type = 0; type < NR_CURSEG_DATA_TYPE; type++) {
737 if (segno == ckpt->cur_data_segno[type]) {
738 curseg = CURSEG_I(sbi, type);
739 memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
740 ASSERT(!IS_SUM_NODE_SEG(sum_blk->footer));
741 DBG(2, "segno [0x%x] is current data seg[0x%x]\n", segno, type);
742 return SEG_TYPE_CUR_DATA; /* current data seg was not stored */
743 }
744 }
745
746 ret = dev_read_block(sum_blk, ssa_blk);
747 ASSERT(ret >= 0);
748
749 if (IS_SUM_NODE_SEG(sum_blk->footer))
750 return SEG_TYPE_NODE;
751 else
752 return SEG_TYPE_DATA;
753
754}
755
756int get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *sum_entry)
757{
758 struct f2fs_summary_block *sum_blk;
759 u32 segno, offset;
760 int ret;
761
762 segno = GET_SEGNO(sbi, blk_addr);
763 offset = OFFSET_IN_SEG(sbi, blk_addr);
764
765 sum_blk = calloc(BLOCK_SZ, 1);
766
767 ret = get_sum_block(sbi, segno, sum_blk);
768
769 memcpy(sum_entry, &(sum_blk->entries[offset]), sizeof(struct f2fs_summary));
770
771 free(sum_blk);
772 return ret;
773}
774
775int get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct f2fs_nat_entry *raw_nat)
776{
777 struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
778 struct f2fs_nm_info *nm_i = NM_I(sbi);
779 struct f2fs_nat_block *nat_block;
780 pgoff_t block_off;
781 pgoff_t block_addr;
782 int seg_off, entry_off;
783 int ret;
784
785 if (nid / NAT_ENTRY_PER_BLOCK > (fsck->nat_area_bitmap_sz * 8)) {
786 DBG(0, "\n");
787 return -EINVAL;
788 }
789
790 if (lookup_nat_in_journal(sbi, nid, raw_nat) >= 0)
791 return 0;
792
793 nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
794
795 block_off = nid / NAT_ENTRY_PER_BLOCK;
796 entry_off = nid % NAT_ENTRY_PER_BLOCK;
797
798 seg_off = block_off >> sbi->log_blocks_per_seg;
799 block_addr = (pgoff_t)(nm_i->nat_blkaddr +
800 (seg_off << sbi->log_blocks_per_seg << 1) +
801 (block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
802
803 if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
804 block_addr += sbi->blocks_per_seg;
805
806 ret = dev_read_block(nat_block, block_addr);
807 ASSERT(ret >= 0);
808
809 memcpy(raw_nat, &nat_block->entries[entry_off], sizeof(struct f2fs_nat_entry));
810 free(nat_block);
811
812 return 0;
813}
814
815int get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
816{
817 struct f2fs_nat_entry raw_nat;
818 int ret;
819
820 ret = get_nat_entry(sbi, nid, &raw_nat);
821 ni->nid = nid;
822 node_info_from_raw_nat(ni, &raw_nat);
823 return ret;
824}
825
826void build_sit_entries(struct f2fs_sb_info *sbi)
827{
828 struct sit_info *sit_i = SIT_I(sbi);
829 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
830 struct f2fs_summary_block *sum = curseg->sum_blk;
831 unsigned int segno;
832
833 for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
834 struct seg_entry *se = &sit_i->sentries[segno];
835 struct f2fs_sit_block *sit_blk;
836 struct f2fs_sit_entry sit;
837 int i;
838
839 for (i = 0; i < sits_in_cursum(sum); i++) {
840 if (le32_to_cpu(segno_in_journal(sum, i)) == segno) {
841 sit = sit_in_journal(sum, i);
842 goto got_it;
843 }
844 }
845 sit_blk = get_current_sit_page(sbi, segno);
846 sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, segno)];
847 free(sit_blk);
848got_it:
849 check_block_count(sbi, segno, &sit);
850 seg_info_from_raw_sit(se, &sit);
851 }
852
853}
854
855int build_segment_manager(struct f2fs_sb_info *sbi)
856{
857 struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
858 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
859 struct f2fs_sm_info *sm_info;
860
861 sm_info = malloc(sizeof(struct f2fs_sm_info));
862 if (!sm_info)
863 return -ENOMEM;
864
865 /* init sm info */
866 sbi->sm_info = sm_info;
867 sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
868 sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
869 sm_info->segment_count = le32_to_cpu(raw_super->segment_count);
870 sm_info->reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
871 sm_info->ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
872 sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main);
873 sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
874
875 build_sit_info(sbi);
876
877 build_curseg(sbi);
878
879 build_sit_entries(sbi);
880
881 return 0;
882}
883
884int build_sit_area_bitmap(struct f2fs_sb_info *sbi)
885{
886 struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
887 struct f2fs_sm_info *sm_i = SM_I(sbi);
888 int segno = 0, j = 0;
889 char *ptr = NULL;
890
891 u32 sum_vblocks = 0;
892 u32 free_segs = 0;
893 u32 vblocks = 0;
894
895 struct seg_entry *se;
896
897 fsck->sit_area_bitmap_sz = sm_i->main_segments * SIT_VBLOCK_MAP_SIZE;
898 fsck->sit_area_bitmap = calloc(1, fsck->sit_area_bitmap_sz);
899 ptr = fsck->sit_area_bitmap;
900
901 ASSERT(fsck->sit_area_bitmap_sz == fsck->main_area_bitmap_sz);
902
903 for (segno = 0; segno < sm_i->main_segments; segno++) {
904 se = get_seg_entry(sbi, segno);
905
906 memcpy(ptr, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
907 ptr += SIT_VBLOCK_MAP_SIZE;
908
909 vblocks = 0;
910 for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) {
911 vblocks += get_bits_in_byte(se->cur_valid_map[j]);
912 }
913 ASSERT(vblocks == se->valid_blocks);
914
915 if (se->valid_blocks == 0x0) {
916
917 if (sbi->ckpt->cur_node_segno[0] == segno ||
918 sbi->ckpt->cur_data_segno[0] == segno ||
919 sbi->ckpt->cur_node_segno[1] == segno ||
920 sbi->ckpt->cur_data_segno[1] == segno ||
921 sbi->ckpt->cur_node_segno[2] == segno ||
922 sbi->ckpt->cur_data_segno[2] == segno) {
923 continue;
924 } else {
925 free_segs++;
926 }
927
928 } else {
929 ASSERT(se->valid_blocks <= 512);
930 sum_vblocks += se->valid_blocks;
931 }
932 }
933
934 fsck->chk.sit_valid_blocks = sum_vblocks;
935 fsck->chk.sit_free_segs = free_segs;
936
937 DBG(0, "Blocks [0x%x] Free Segs [0x%x]\n", sum_vblocks, free_segs);
938 return 0;
939}
940
941int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_nat_entry *raw_nat)
942{
943 struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
944 struct f2fs_summary_block *sum = curseg->sum_blk;
945 int i = 0;
946
947 for (i = 0; i < nats_in_cursum(sum); i++) {
948 if (le32_to_cpu(nid_in_journal(sum, i)) == nid) {
949 memcpy(raw_nat, &nat_in_journal(sum, i), sizeof(struct f2fs_nat_entry));
950 DBG(3, "==> Found nid [0x%x] in nat cache\n", nid);
951 return i;
952 }
953 }
954 return -1;
955}
956
957void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
958{
959 struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
960 struct f2fs_super_block *raw_sb = F2FS_RAW_SUPER(sbi);
961 struct f2fs_nm_info *nm_i = NM_I(sbi);
962 struct f2fs_nat_block *nat_block;
963 u32 nid, nr_nat_blks;
964
965 pgoff_t block_off;
966 pgoff_t block_addr;
967 int seg_off;
968 int ret, i;
969
970
971 nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
972
973 /* Alloc & build nat entry bitmap */
974 nr_nat_blks = (le32_to_cpu(raw_sb->segment_count_nat) / 2) << sbi->log_blocks_per_seg;
975
976 fsck->nr_nat_entries = nr_nat_blks * NAT_ENTRY_PER_BLOCK;
977 fsck->nat_area_bitmap_sz = (fsck->nr_nat_entries + 7) / 8;
978 fsck->nat_area_bitmap = calloc(fsck->nat_area_bitmap_sz, 1);
979 ASSERT(fsck->nat_area_bitmap != NULL);
980
981 for (block_off = 0; block_off < nr_nat_blks; block_off++) {
982
983 seg_off = block_off >> sbi->log_blocks_per_seg;
984 block_addr = (pgoff_t)(nm_i->nat_blkaddr +
985 (seg_off << sbi->log_blocks_per_seg << 1) +
986 (block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
987
988 if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
989 block_addr += sbi->blocks_per_seg;
990
991 ret = dev_read_block(nat_block, block_addr);
992 ASSERT(ret >= 0);
993
994 nid = block_off * NAT_ENTRY_PER_BLOCK;
995 for (i = 0; i < NAT_ENTRY_PER_BLOCK; i++) {
996 struct f2fs_nat_entry raw_nat;
997 struct node_info ni;
998 ni.nid = nid + i;
999
1000 if ((nid + i) == F2FS_NODE_INO(sbi) || (nid + i) == F2FS_META_INO(sbi)) {
1001 ASSERT(nat_block->entries[i].block_addr != 0x0);
1002 continue;
1003 }
1004
1005 if (lookup_nat_in_journal(sbi, nid + i, &raw_nat) >= 0) {
1006 node_info_from_raw_nat(&ni, &raw_nat);
1007 if (ni.blk_addr != 0x0) {
1008 f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
1009 fsck->chk.valid_nat_entry_cnt++;
1010 DBG(3, "nid[0x%x] in nat cache\n", nid + i);
1011 }
1012 } else {
1013 node_info_from_raw_nat(&ni, &nat_block->entries[i]);
1014 if (ni.blk_addr != 0) {
1015 ASSERT(nid + i != 0x0);
1016
1017 DBG(3, "nid[0x%8x] in nat entry [0x%16x] [0x%8x]\n",
1018 nid + i,
1019 ni.blk_addr,
1020 ni.ino);
1021
1022 f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
1023 fsck->chk.valid_nat_entry_cnt++;
1024 }
1025 }
1026 }
1027 }
1028 free(nat_block);
1029
1030 DBG(0, "valid nat entries (block_addr != 0x0) [0x%8x : %u]\n",
1031 fsck->chk.valid_nat_entry_cnt, fsck->chk.valid_nat_entry_cnt);
1032
1033}
1034
1035int f2fs_do_mount(struct f2fs_sb_info *sbi)
1036{
1037 int ret;
1038 sbi->active_logs = NR_CURSEG_TYPE;
1039 ret = validate_super_block(sbi, 0);
1040 if (ret) {
1041 ret = validate_super_block(sbi, 1);
1042 if (ret)
1043 return -1;
1044 }
1045
1046 print_raw_sb_info(sbi);
1047
1048 init_sb_info(sbi);
1049
1050 ret = get_valid_checkpoint(sbi);
1051 if (ret) {
1052 ERR_MSG("Can't find valid checkpoint\n");
1053 return -1;
1054 }
1055
1056 if (sanity_check_ckpt(sbi)) {
1057 ERR_MSG("Checkpoint is polluted\n");
1058 return -1;
1059 }
1060
1061 print_ckpt_info(sbi);
1062
1063 sbi->total_valid_node_count = le32_to_cpu(sbi->ckpt->valid_node_count);
1064 sbi->total_valid_inode_count = le32_to_cpu(sbi->ckpt->valid_inode_count);
1065 sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);
1066 sbi->total_valid_block_count = le64_to_cpu(sbi->ckpt->valid_block_count);
1067 sbi->last_valid_block_count = sbi->total_valid_block_count;
1068 sbi->alloc_valid_block_count = 0;
1069
1070 if (build_segment_manager(sbi)) {
1071 ERR_MSG("build_segment_manager failed\n");
1072 return -1;
1073 }
1074
1075 if (build_node_manager(sbi)) {
1076 ERR_MSG("build_segment_manager failed\n");
1077 return -1;
1078 }
1079
1080 return ret;
1081}
1082
1083void f2fs_do_umount(struct f2fs_sb_info *sbi)
1084{
1085 struct sit_info *sit_i = SIT_I(sbi);
1086 struct f2fs_sm_info *sm_i = SM_I(sbi);
1087 struct f2fs_nm_info *nm_i = NM_I(sbi);
1088 int i;
1089
1090 /* free nm_info */
1091 free(nm_i->nat_bitmap);
1092 free(sbi->nm_info);
1093
1094 /* free sit_info */
1095 for (i = 0; i < TOTAL_SEGS(sbi); i++) {
1096 free(sit_i->sentries[i].cur_valid_map);
1097 free(sit_i->sentries[i].ckpt_valid_map);
1098 }
1099 free(sit_i->sit_bitmap);
1100 free(sm_i->sit_info);
1101
1102 /* free sm_info */
1103 for (i = 0; i < NR_CURSEG_TYPE; i++)
1104 free(sm_i->curseg_array[i].sum_blk);
1105
1106 free(sm_i->curseg_array);
1107 free(sbi->sm_info);
1108
1109 free(sbi->ckpt);
1110 free(sbi->raw_super);
1111}