mount.c revision 7f35b548d4b0e3c8577ad7a09433e589a0ab3f2a
1/**
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}
1112