xref: /aosp_15_r20/external/f2fs-tools/fsck/resize.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker /**
2*59bfda1fSAndroid Build Coastguard Worker  * resize.c
3*59bfda1fSAndroid Build Coastguard Worker  *
4*59bfda1fSAndroid Build Coastguard Worker  * Copyright (c) 2015 Jaegeuk Kim <[email protected]>
5*59bfda1fSAndroid Build Coastguard Worker  *
6*59bfda1fSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify
7*59bfda1fSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License version 2 as
8*59bfda1fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
9*59bfda1fSAndroid Build Coastguard Worker  */
10*59bfda1fSAndroid Build Coastguard Worker #include "fsck.h"
11*59bfda1fSAndroid Build Coastguard Worker 
get_new_sb(struct f2fs_super_block * sb)12*59bfda1fSAndroid Build Coastguard Worker static int get_new_sb(struct f2fs_super_block *sb)
13*59bfda1fSAndroid Build Coastguard Worker {
14*59bfda1fSAndroid Build Coastguard Worker 	uint32_t zone_size_bytes;
15*59bfda1fSAndroid Build Coastguard Worker 	uint64_t zone_align_start_offset;
16*59bfda1fSAndroid Build Coastguard Worker 	uint32_t blocks_for_sit, blocks_for_nat, blocks_for_ssa;
17*59bfda1fSAndroid Build Coastguard Worker 	uint32_t sit_segments, nat_segments, diff, total_meta_segments;
18*59bfda1fSAndroid Build Coastguard Worker 	uint32_t total_valid_blks_available;
19*59bfda1fSAndroid Build Coastguard Worker 	uint32_t sit_bitmap_size, max_sit_bitmap_size;
20*59bfda1fSAndroid Build Coastguard Worker 	uint32_t max_nat_bitmap_size, max_nat_segments;
21*59bfda1fSAndroid Build Coastguard Worker 	uint32_t segment_size_bytes = 1 << (get_sb(log_blocksize) +
22*59bfda1fSAndroid Build Coastguard Worker 					get_sb(log_blocks_per_seg));
23*59bfda1fSAndroid Build Coastguard Worker 	uint32_t blks_per_seg = 1 << get_sb(log_blocks_per_seg);
24*59bfda1fSAndroid Build Coastguard Worker 	uint32_t segs_per_zone = get_sb(segs_per_sec) * get_sb(secs_per_zone);
25*59bfda1fSAndroid Build Coastguard Worker 
26*59bfda1fSAndroid Build Coastguard Worker 	set_sb(block_count, c.target_sectors >>
27*59bfda1fSAndroid Build Coastguard Worker 				get_sb(log_sectors_per_block));
28*59bfda1fSAndroid Build Coastguard Worker 
29*59bfda1fSAndroid Build Coastguard Worker 	zone_size_bytes = segment_size_bytes * segs_per_zone;
30*59bfda1fSAndroid Build Coastguard Worker 	zone_align_start_offset =
31*59bfda1fSAndroid Build Coastguard Worker 		((uint64_t) c.start_sector * DEFAULT_SECTOR_SIZE +
32*59bfda1fSAndroid Build Coastguard Worker 		2 * F2FS_BLKSIZE + zone_size_bytes - 1) /
33*59bfda1fSAndroid Build Coastguard Worker 		zone_size_bytes * zone_size_bytes -
34*59bfda1fSAndroid Build Coastguard Worker 		(uint64_t) c.start_sector * DEFAULT_SECTOR_SIZE;
35*59bfda1fSAndroid Build Coastguard Worker 
36*59bfda1fSAndroid Build Coastguard Worker 	set_sb(segment_count, (c.target_sectors * c.sector_size -
37*59bfda1fSAndroid Build Coastguard Worker 				zone_align_start_offset) / segment_size_bytes /
38*59bfda1fSAndroid Build Coastguard Worker 				c.segs_per_sec * c.segs_per_sec);
39*59bfda1fSAndroid Build Coastguard Worker 
40*59bfda1fSAndroid Build Coastguard Worker 	if (c.safe_resize)
41*59bfda1fSAndroid Build Coastguard Worker 		goto safe_resize;
42*59bfda1fSAndroid Build Coastguard Worker 
43*59bfda1fSAndroid Build Coastguard Worker 	blocks_for_sit = SIZE_ALIGN(get_sb(segment_count), SIT_ENTRY_PER_BLOCK);
44*59bfda1fSAndroid Build Coastguard Worker 	sit_segments = SEG_ALIGN(blocks_for_sit);
45*59bfda1fSAndroid Build Coastguard Worker 	set_sb(segment_count_sit, sit_segments * 2);
46*59bfda1fSAndroid Build Coastguard Worker 	set_sb(nat_blkaddr, get_sb(sit_blkaddr) +
47*59bfda1fSAndroid Build Coastguard Worker 				get_sb(segment_count_sit) * blks_per_seg);
48*59bfda1fSAndroid Build Coastguard Worker 
49*59bfda1fSAndroid Build Coastguard Worker 	total_valid_blks_available = (get_sb(segment_count) -
50*59bfda1fSAndroid Build Coastguard Worker 			(get_sb(segment_count_ckpt) +
51*59bfda1fSAndroid Build Coastguard Worker 			get_sb(segment_count_sit))) * blks_per_seg;
52*59bfda1fSAndroid Build Coastguard Worker 	blocks_for_nat = SIZE_ALIGN(total_valid_blks_available,
53*59bfda1fSAndroid Build Coastguard Worker 					NAT_ENTRY_PER_BLOCK);
54*59bfda1fSAndroid Build Coastguard Worker 
55*59bfda1fSAndroid Build Coastguard Worker 	if (c.large_nat_bitmap) {
56*59bfda1fSAndroid Build Coastguard Worker 		nat_segments = SEG_ALIGN(blocks_for_nat) *
57*59bfda1fSAndroid Build Coastguard Worker 						DEFAULT_NAT_ENTRY_RATIO / 100;
58*59bfda1fSAndroid Build Coastguard Worker 		set_sb(segment_count_nat, nat_segments ? nat_segments : 1);
59*59bfda1fSAndroid Build Coastguard Worker 
60*59bfda1fSAndroid Build Coastguard Worker 		max_nat_bitmap_size = (get_sb(segment_count_nat) <<
61*59bfda1fSAndroid Build Coastguard Worker 						get_sb(log_blocks_per_seg)) / 8;
62*59bfda1fSAndroid Build Coastguard Worker 		set_sb(segment_count_nat, get_sb(segment_count_nat) * 2);
63*59bfda1fSAndroid Build Coastguard Worker 	} else {
64*59bfda1fSAndroid Build Coastguard Worker 		set_sb(segment_count_nat, SEG_ALIGN(blocks_for_nat));
65*59bfda1fSAndroid Build Coastguard Worker 		max_nat_bitmap_size = 0;
66*59bfda1fSAndroid Build Coastguard Worker 	}
67*59bfda1fSAndroid Build Coastguard Worker 
68*59bfda1fSAndroid Build Coastguard Worker 	sit_bitmap_size = ((get_sb(segment_count_sit) / 2) <<
69*59bfda1fSAndroid Build Coastguard Worker 				get_sb(log_blocks_per_seg)) / 8;
70*59bfda1fSAndroid Build Coastguard Worker 	if (sit_bitmap_size > MAX_SIT_BITMAP_SIZE)
71*59bfda1fSAndroid Build Coastguard Worker 		max_sit_bitmap_size = MAX_SIT_BITMAP_SIZE;
72*59bfda1fSAndroid Build Coastguard Worker 	else
73*59bfda1fSAndroid Build Coastguard Worker 		max_sit_bitmap_size = sit_bitmap_size;
74*59bfda1fSAndroid Build Coastguard Worker 
75*59bfda1fSAndroid Build Coastguard Worker 	if (c.large_nat_bitmap) {
76*59bfda1fSAndroid Build Coastguard Worker 		/* use cp_payload if free space of f2fs_checkpoint is not enough */
77*59bfda1fSAndroid Build Coastguard Worker 		if (max_sit_bitmap_size + max_nat_bitmap_size >
78*59bfda1fSAndroid Build Coastguard Worker 						MAX_BITMAP_SIZE_IN_CKPT) {
79*59bfda1fSAndroid Build Coastguard Worker 			uint32_t diff =  max_sit_bitmap_size +
80*59bfda1fSAndroid Build Coastguard Worker 						max_nat_bitmap_size -
81*59bfda1fSAndroid Build Coastguard Worker 						MAX_BITMAP_SIZE_IN_CKPT;
82*59bfda1fSAndroid Build Coastguard Worker 			set_sb(cp_payload, F2FS_BLK_ALIGN(diff));
83*59bfda1fSAndroid Build Coastguard Worker 		} else {
84*59bfda1fSAndroid Build Coastguard Worker 			set_sb(cp_payload, 0);
85*59bfda1fSAndroid Build Coastguard Worker 		}
86*59bfda1fSAndroid Build Coastguard Worker 	} else {
87*59bfda1fSAndroid Build Coastguard Worker 		/*
88*59bfda1fSAndroid Build Coastguard Worker 		 * It should be reserved minimum 1 segment for nat.
89*59bfda1fSAndroid Build Coastguard Worker 		 * When sit is too large, we should expand cp area.
90*59bfda1fSAndroid Build Coastguard Worker 		 * It requires more pages for cp.
91*59bfda1fSAndroid Build Coastguard Worker 		 */
92*59bfda1fSAndroid Build Coastguard Worker 		if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) {
93*59bfda1fSAndroid Build Coastguard Worker 			max_nat_bitmap_size = MAX_BITMAP_SIZE_IN_CKPT;
94*59bfda1fSAndroid Build Coastguard Worker 			set_sb(cp_payload, F2FS_BLK_ALIGN(max_sit_bitmap_size));
95*59bfda1fSAndroid Build Coastguard Worker 		} else {
96*59bfda1fSAndroid Build Coastguard Worker 			max_nat_bitmap_size = MAX_BITMAP_SIZE_IN_CKPT -
97*59bfda1fSAndroid Build Coastguard Worker 							max_sit_bitmap_size;
98*59bfda1fSAndroid Build Coastguard Worker 			set_sb(cp_payload, 0);
99*59bfda1fSAndroid Build Coastguard Worker 		}
100*59bfda1fSAndroid Build Coastguard Worker 
101*59bfda1fSAndroid Build Coastguard Worker 		max_nat_segments = (max_nat_bitmap_size * 8) >>
102*59bfda1fSAndroid Build Coastguard Worker 					get_sb(log_blocks_per_seg);
103*59bfda1fSAndroid Build Coastguard Worker 
104*59bfda1fSAndroid Build Coastguard Worker 		if (get_sb(segment_count_nat) > max_nat_segments)
105*59bfda1fSAndroid Build Coastguard Worker 			set_sb(segment_count_nat, max_nat_segments);
106*59bfda1fSAndroid Build Coastguard Worker 
107*59bfda1fSAndroid Build Coastguard Worker 		set_sb(segment_count_nat, get_sb(segment_count_nat) * 2);
108*59bfda1fSAndroid Build Coastguard Worker 	}
109*59bfda1fSAndroid Build Coastguard Worker 
110*59bfda1fSAndroid Build Coastguard Worker 	set_sb(ssa_blkaddr, get_sb(nat_blkaddr) +
111*59bfda1fSAndroid Build Coastguard Worker 				get_sb(segment_count_nat) * blks_per_seg);
112*59bfda1fSAndroid Build Coastguard Worker 
113*59bfda1fSAndroid Build Coastguard Worker 	total_valid_blks_available = (get_sb(segment_count) -
114*59bfda1fSAndroid Build Coastguard Worker 			(get_sb(segment_count_ckpt) +
115*59bfda1fSAndroid Build Coastguard Worker 			get_sb(segment_count_sit) +
116*59bfda1fSAndroid Build Coastguard Worker 			get_sb(segment_count_nat))) * blks_per_seg;
117*59bfda1fSAndroid Build Coastguard Worker 
118*59bfda1fSAndroid Build Coastguard Worker 	blocks_for_ssa = total_valid_blks_available / blks_per_seg + 1;
119*59bfda1fSAndroid Build Coastguard Worker 
120*59bfda1fSAndroid Build Coastguard Worker 	set_sb(segment_count_ssa, SEG_ALIGN(blocks_for_ssa));
121*59bfda1fSAndroid Build Coastguard Worker 
122*59bfda1fSAndroid Build Coastguard Worker 	total_meta_segments = get_sb(segment_count_ckpt) +
123*59bfda1fSAndroid Build Coastguard Worker 		get_sb(segment_count_sit) +
124*59bfda1fSAndroid Build Coastguard Worker 		get_sb(segment_count_nat) +
125*59bfda1fSAndroid Build Coastguard Worker 		get_sb(segment_count_ssa);
126*59bfda1fSAndroid Build Coastguard Worker 
127*59bfda1fSAndroid Build Coastguard Worker 	diff = total_meta_segments % segs_per_zone;
128*59bfda1fSAndroid Build Coastguard Worker 	if (diff)
129*59bfda1fSAndroid Build Coastguard Worker 		set_sb(segment_count_ssa, get_sb(segment_count_ssa) +
130*59bfda1fSAndroid Build Coastguard Worker 			(segs_per_zone - diff));
131*59bfda1fSAndroid Build Coastguard Worker 
132*59bfda1fSAndroid Build Coastguard Worker 	set_sb(main_blkaddr, get_sb(ssa_blkaddr) + get_sb(segment_count_ssa) *
133*59bfda1fSAndroid Build Coastguard Worker 			 blks_per_seg);
134*59bfda1fSAndroid Build Coastguard Worker 
135*59bfda1fSAndroid Build Coastguard Worker safe_resize:
136*59bfda1fSAndroid Build Coastguard Worker 	set_sb(segment_count_main, get_sb(segment_count) -
137*59bfda1fSAndroid Build Coastguard Worker 			(get_sb(segment_count_ckpt) +
138*59bfda1fSAndroid Build Coastguard Worker 			 get_sb(segment_count_sit) +
139*59bfda1fSAndroid Build Coastguard Worker 			 get_sb(segment_count_nat) +
140*59bfda1fSAndroid Build Coastguard Worker 			 get_sb(segment_count_ssa)));
141*59bfda1fSAndroid Build Coastguard Worker 
142*59bfda1fSAndroid Build Coastguard Worker 	set_sb(section_count, get_sb(segment_count_main) /
143*59bfda1fSAndroid Build Coastguard Worker 						get_sb(segs_per_sec));
144*59bfda1fSAndroid Build Coastguard Worker 
145*59bfda1fSAndroid Build Coastguard Worker 	set_sb(segment_count_main, get_sb(section_count) *
146*59bfda1fSAndroid Build Coastguard Worker 						get_sb(segs_per_sec));
147*59bfda1fSAndroid Build Coastguard Worker 
148*59bfda1fSAndroid Build Coastguard Worker 	/* Let's determine the best reserved and overprovisioned space */
149*59bfda1fSAndroid Build Coastguard Worker 	if (c.new_overprovision == 0)
150*59bfda1fSAndroid Build Coastguard Worker 		c.new_overprovision = get_best_overprovision(sb);
151*59bfda1fSAndroid Build Coastguard Worker 
152*59bfda1fSAndroid Build Coastguard Worker 	c.new_reserved_segments =
153*59bfda1fSAndroid Build Coastguard Worker 		(100 / c.new_overprovision + 1 + NR_CURSEG_TYPE) *
154*59bfda1fSAndroid Build Coastguard Worker 						get_sb(segs_per_sec);
155*59bfda1fSAndroid Build Coastguard Worker 
156*59bfda1fSAndroid Build Coastguard Worker 	if ((get_sb(segment_count_main) - 2) < c.new_reserved_segments ||
157*59bfda1fSAndroid Build Coastguard Worker 		get_sb(segment_count_main) * blks_per_seg >
158*59bfda1fSAndroid Build Coastguard Worker 						get_sb(block_count)) {
159*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "\tError: Device size is not sufficient for F2FS volume, "
160*59bfda1fSAndroid Build Coastguard Worker 			"more segment needed =%u",
161*59bfda1fSAndroid Build Coastguard Worker 			c.new_reserved_segments -
162*59bfda1fSAndroid Build Coastguard Worker 			(get_sb(segment_count_main) - 2));
163*59bfda1fSAndroid Build Coastguard Worker 		return -1;
164*59bfda1fSAndroid Build Coastguard Worker 	}
165*59bfda1fSAndroid Build Coastguard Worker 	return 0;
166*59bfda1fSAndroid Build Coastguard Worker }
167*59bfda1fSAndroid Build Coastguard Worker 
migrate_main(struct f2fs_sb_info * sbi,unsigned int offset)168*59bfda1fSAndroid Build Coastguard Worker static void migrate_main(struct f2fs_sb_info *sbi, unsigned int offset)
169*59bfda1fSAndroid Build Coastguard Worker {
170*59bfda1fSAndroid Build Coastguard Worker 	void *raw = calloc(F2FS_BLKSIZE, 1);
171*59bfda1fSAndroid Build Coastguard Worker 	struct seg_entry *se;
172*59bfda1fSAndroid Build Coastguard Worker 	block_t from, to;
173*59bfda1fSAndroid Build Coastguard Worker 	int i, j, ret;
174*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_summary sum;
175*59bfda1fSAndroid Build Coastguard Worker 
176*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(raw != NULL);
177*59bfda1fSAndroid Build Coastguard Worker 
178*59bfda1fSAndroid Build Coastguard Worker 	for (i = MAIN_SEGS(sbi) - 1; i >= 0; i--) {
179*59bfda1fSAndroid Build Coastguard Worker 		se = get_seg_entry(sbi, i);
180*59bfda1fSAndroid Build Coastguard Worker 		if (!se->valid_blocks)
181*59bfda1fSAndroid Build Coastguard Worker 			continue;
182*59bfda1fSAndroid Build Coastguard Worker 
183*59bfda1fSAndroid Build Coastguard Worker 		for (j = sbi->blocks_per_seg - 1; j >= 0; j--) {
184*59bfda1fSAndroid Build Coastguard Worker 			if (!f2fs_test_bit(j, (const char *)se->cur_valid_map))
185*59bfda1fSAndroid Build Coastguard Worker 				continue;
186*59bfda1fSAndroid Build Coastguard Worker 
187*59bfda1fSAndroid Build Coastguard Worker 			from = START_BLOCK(sbi, i) + j;
188*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_read_block(raw, from);
189*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
190*59bfda1fSAndroid Build Coastguard Worker 
191*59bfda1fSAndroid Build Coastguard Worker 			to = from + offset;
192*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_write_block(raw, to,
193*59bfda1fSAndroid Build Coastguard Worker 					      f2fs_io_type_to_rw_hint(se->type));
194*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
195*59bfda1fSAndroid Build Coastguard Worker 
196*59bfda1fSAndroid Build Coastguard Worker 			get_sum_entry(sbi, from, &sum);
197*59bfda1fSAndroid Build Coastguard Worker 
198*59bfda1fSAndroid Build Coastguard Worker 			if (IS_DATASEG(se->type))
199*59bfda1fSAndroid Build Coastguard Worker 				update_data_blkaddr(sbi, le32_to_cpu(sum.nid),
200*59bfda1fSAndroid Build Coastguard Worker 					le16_to_cpu(sum.ofs_in_node), to, NULL);
201*59bfda1fSAndroid Build Coastguard Worker 			else
202*59bfda1fSAndroid Build Coastguard Worker 				update_nat_blkaddr(sbi, 0,
203*59bfda1fSAndroid Build Coastguard Worker 						le32_to_cpu(sum.nid), to);
204*59bfda1fSAndroid Build Coastguard Worker 		}
205*59bfda1fSAndroid Build Coastguard Worker 	}
206*59bfda1fSAndroid Build Coastguard Worker 	free(raw);
207*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Done to migrate Main area: main_blkaddr = 0x%x -> 0x%x\n",
208*59bfda1fSAndroid Build Coastguard Worker 				START_BLOCK(sbi, 0),
209*59bfda1fSAndroid Build Coastguard Worker 				START_BLOCK(sbi, 0) + offset);
210*59bfda1fSAndroid Build Coastguard Worker }
211*59bfda1fSAndroid Build Coastguard Worker 
move_ssa(struct f2fs_sb_info * sbi,unsigned int segno,block_t new_sum_blk_addr)212*59bfda1fSAndroid Build Coastguard Worker static void move_ssa(struct f2fs_sb_info *sbi, unsigned int segno,
213*59bfda1fSAndroid Build Coastguard Worker 					block_t new_sum_blk_addr)
214*59bfda1fSAndroid Build Coastguard Worker {
215*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_summary_block *sum_blk;
216*59bfda1fSAndroid Build Coastguard Worker 	int type;
217*59bfda1fSAndroid Build Coastguard Worker 
218*59bfda1fSAndroid Build Coastguard Worker 	sum_blk = get_sum_block(sbi, segno, &type);
219*59bfda1fSAndroid Build Coastguard Worker 	if (type < SEG_TYPE_MAX) {
220*59bfda1fSAndroid Build Coastguard Worker 		int ret;
221*59bfda1fSAndroid Build Coastguard Worker 
222*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(sum_blk, new_sum_blk_addr,
223*59bfda1fSAndroid Build Coastguard Worker 				      WRITE_LIFE_NONE);
224*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
225*59bfda1fSAndroid Build Coastguard Worker 		DBG(1, "Write summary block: (%d) segno=%x/%x --> (%d) %x\n",
226*59bfda1fSAndroid Build Coastguard Worker 				type, segno, GET_SUM_BLKADDR(sbi, segno),
227*59bfda1fSAndroid Build Coastguard Worker 				IS_SUM_NODE_SEG(sum_blk),
228*59bfda1fSAndroid Build Coastguard Worker 				new_sum_blk_addr);
229*59bfda1fSAndroid Build Coastguard Worker 	}
230*59bfda1fSAndroid Build Coastguard Worker 	if (type == SEG_TYPE_NODE || type == SEG_TYPE_DATA ||
231*59bfda1fSAndroid Build Coastguard Worker 			type == SEG_TYPE_MAX) {
232*59bfda1fSAndroid Build Coastguard Worker 		free(sum_blk);
233*59bfda1fSAndroid Build Coastguard Worker 	}
234*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "Info: Done to migrate SSA blocks\n");
235*59bfda1fSAndroid Build Coastguard Worker }
236*59bfda1fSAndroid Build Coastguard Worker 
migrate_ssa(struct f2fs_sb_info * sbi,struct f2fs_super_block * new_sb,unsigned int offset)237*59bfda1fSAndroid Build Coastguard Worker static void migrate_ssa(struct f2fs_sb_info *sbi,
238*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_super_block *new_sb, unsigned int offset)
239*59bfda1fSAndroid Build Coastguard Worker {
240*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
241*59bfda1fSAndroid Build Coastguard Worker 	block_t old_sum_blkaddr = get_sb(ssa_blkaddr);
242*59bfda1fSAndroid Build Coastguard Worker 	block_t new_sum_blkaddr = get_newsb(ssa_blkaddr);
243*59bfda1fSAndroid Build Coastguard Worker 	block_t end_sum_blkaddr = get_newsb(main_blkaddr);
244*59bfda1fSAndroid Build Coastguard Worker 	block_t expand_sum_blkaddr = new_sum_blkaddr +
245*59bfda1fSAndroid Build Coastguard Worker 					MAIN_SEGS(sbi) - offset;
246*59bfda1fSAndroid Build Coastguard Worker 	block_t blkaddr;
247*59bfda1fSAndroid Build Coastguard Worker 	int ret;
248*59bfda1fSAndroid Build Coastguard Worker 	void *zero_block = calloc(F2FS_BLKSIZE, 1);
249*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(zero_block);
250*59bfda1fSAndroid Build Coastguard Worker 
251*59bfda1fSAndroid Build Coastguard Worker 	if (offset && new_sum_blkaddr < old_sum_blkaddr + offset) {
252*59bfda1fSAndroid Build Coastguard Worker 		blkaddr = new_sum_blkaddr;
253*59bfda1fSAndroid Build Coastguard Worker 		while (blkaddr < end_sum_blkaddr) {
254*59bfda1fSAndroid Build Coastguard Worker 			if (blkaddr < expand_sum_blkaddr) {
255*59bfda1fSAndroid Build Coastguard Worker 				move_ssa(sbi, offset++, blkaddr++);
256*59bfda1fSAndroid Build Coastguard Worker 			} else {
257*59bfda1fSAndroid Build Coastguard Worker 				ret = dev_write_block(zero_block, blkaddr++,
258*59bfda1fSAndroid Build Coastguard Worker 						      WRITE_LIFE_NONE);
259*59bfda1fSAndroid Build Coastguard Worker 				ASSERT(ret >=0);
260*59bfda1fSAndroid Build Coastguard Worker 			}
261*59bfda1fSAndroid Build Coastguard Worker 		}
262*59bfda1fSAndroid Build Coastguard Worker 	} else {
263*59bfda1fSAndroid Build Coastguard Worker 		blkaddr = end_sum_blkaddr - 1;
264*59bfda1fSAndroid Build Coastguard Worker 		offset = MAIN_SEGS(sbi) - 1;
265*59bfda1fSAndroid Build Coastguard Worker 		while (blkaddr >= new_sum_blkaddr) {
266*59bfda1fSAndroid Build Coastguard Worker 			if (blkaddr >= expand_sum_blkaddr) {
267*59bfda1fSAndroid Build Coastguard Worker 				ret = dev_write_block(zero_block, blkaddr--,
268*59bfda1fSAndroid Build Coastguard Worker 						      WRITE_LIFE_NONE);
269*59bfda1fSAndroid Build Coastguard Worker 				ASSERT(ret >=0);
270*59bfda1fSAndroid Build Coastguard Worker 			} else {
271*59bfda1fSAndroid Build Coastguard Worker 				move_ssa(sbi, offset--, blkaddr--);
272*59bfda1fSAndroid Build Coastguard Worker 			}
273*59bfda1fSAndroid Build Coastguard Worker 		}
274*59bfda1fSAndroid Build Coastguard Worker 	}
275*59bfda1fSAndroid Build Coastguard Worker 
276*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Done to migrate SSA blocks: sum_blkaddr = 0x%x -> 0x%x\n",
277*59bfda1fSAndroid Build Coastguard Worker 				old_sum_blkaddr, new_sum_blkaddr);
278*59bfda1fSAndroid Build Coastguard Worker 	free(zero_block);
279*59bfda1fSAndroid Build Coastguard Worker }
280*59bfda1fSAndroid Build Coastguard Worker 
shrink_nats(struct f2fs_sb_info * sbi,struct f2fs_super_block * new_sb)281*59bfda1fSAndroid Build Coastguard Worker static int shrink_nats(struct f2fs_sb_info *sbi,
282*59bfda1fSAndroid Build Coastguard Worker 				struct f2fs_super_block *new_sb)
283*59bfda1fSAndroid Build Coastguard Worker {
284*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
285*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_nm_info *nm_i = NM_I(sbi);
286*59bfda1fSAndroid Build Coastguard Worker 	block_t old_nat_blkaddr = get_sb(nat_blkaddr);
287*59bfda1fSAndroid Build Coastguard Worker 	unsigned int nat_blocks;
288*59bfda1fSAndroid Build Coastguard Worker 	void *nat_block, *zero_block;
289*59bfda1fSAndroid Build Coastguard Worker 	int nid, ret, new_max_nid;
290*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t block_off;
291*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t block_addr;
292*59bfda1fSAndroid Build Coastguard Worker 	int seg_off;
293*59bfda1fSAndroid Build Coastguard Worker 
294*59bfda1fSAndroid Build Coastguard Worker 	nat_block = malloc(F2FS_BLKSIZE);
295*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(nat_block);
296*59bfda1fSAndroid Build Coastguard Worker 	zero_block = calloc(F2FS_BLKSIZE, 1);
297*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(zero_block);
298*59bfda1fSAndroid Build Coastguard Worker 
299*59bfda1fSAndroid Build Coastguard Worker 	nat_blocks = get_newsb(segment_count_nat) >> 1;
300*59bfda1fSAndroid Build Coastguard Worker 	nat_blocks = nat_blocks << get_sb(log_blocks_per_seg);
301*59bfda1fSAndroid Build Coastguard Worker 	new_max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks;
302*59bfda1fSAndroid Build Coastguard Worker 
303*59bfda1fSAndroid Build Coastguard Worker 	for (nid = nm_i->max_nid - 1; nid > new_max_nid; nid -= NAT_ENTRY_PER_BLOCK) {
304*59bfda1fSAndroid Build Coastguard Worker 		block_off = nid / NAT_ENTRY_PER_BLOCK;
305*59bfda1fSAndroid Build Coastguard Worker 		seg_off = block_off >> sbi->log_blocks_per_seg;
306*59bfda1fSAndroid Build Coastguard Worker 		block_addr = (pgoff_t)(old_nat_blkaddr +
307*59bfda1fSAndroid Build Coastguard Worker 				(seg_off << sbi->log_blocks_per_seg << 1) +
308*59bfda1fSAndroid Build Coastguard Worker 				(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
309*59bfda1fSAndroid Build Coastguard Worker 
310*59bfda1fSAndroid Build Coastguard Worker 		if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
311*59bfda1fSAndroid Build Coastguard Worker 			block_addr += sbi->blocks_per_seg;
312*59bfda1fSAndroid Build Coastguard Worker 
313*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_read_block(nat_block, block_addr);
314*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
315*59bfda1fSAndroid Build Coastguard Worker 
316*59bfda1fSAndroid Build Coastguard Worker 		if (memcmp(zero_block, nat_block, F2FS_BLKSIZE)) {
317*59bfda1fSAndroid Build Coastguard Worker 			ret = -1;
318*59bfda1fSAndroid Build Coastguard Worker 			goto not_avail;
319*59bfda1fSAndroid Build Coastguard Worker 		}
320*59bfda1fSAndroid Build Coastguard Worker 	}
321*59bfda1fSAndroid Build Coastguard Worker 	ret = 0;
322*59bfda1fSAndroid Build Coastguard Worker 	nm_i->max_nid = new_max_nid;
323*59bfda1fSAndroid Build Coastguard Worker not_avail:
324*59bfda1fSAndroid Build Coastguard Worker 	free(nat_block);
325*59bfda1fSAndroid Build Coastguard Worker 	free(zero_block);
326*59bfda1fSAndroid Build Coastguard Worker 	return ret;
327*59bfda1fSAndroid Build Coastguard Worker }
328*59bfda1fSAndroid Build Coastguard Worker 
migrate_nat(struct f2fs_sb_info * sbi,struct f2fs_super_block * new_sb)329*59bfda1fSAndroid Build Coastguard Worker static void migrate_nat(struct f2fs_sb_info *sbi,
330*59bfda1fSAndroid Build Coastguard Worker 			struct f2fs_super_block *new_sb)
331*59bfda1fSAndroid Build Coastguard Worker {
332*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
333*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_nm_info *nm_i = NM_I(sbi);
334*59bfda1fSAndroid Build Coastguard Worker 	block_t old_nat_blkaddr = get_sb(nat_blkaddr);
335*59bfda1fSAndroid Build Coastguard Worker 	block_t new_nat_blkaddr = get_newsb(nat_blkaddr);
336*59bfda1fSAndroid Build Coastguard Worker 	unsigned int nat_blocks;
337*59bfda1fSAndroid Build Coastguard Worker 	void *nat_block;
338*59bfda1fSAndroid Build Coastguard Worker 	int nid, ret, new_max_nid;
339*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t block_off;
340*59bfda1fSAndroid Build Coastguard Worker 	pgoff_t block_addr;
341*59bfda1fSAndroid Build Coastguard Worker 	int seg_off;
342*59bfda1fSAndroid Build Coastguard Worker 
343*59bfda1fSAndroid Build Coastguard Worker 	nat_block = malloc(F2FS_BLKSIZE);
344*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(nat_block);
345*59bfda1fSAndroid Build Coastguard Worker 
346*59bfda1fSAndroid Build Coastguard Worker 	for (nid = nm_i->max_nid - 1; nid >= 0; nid -= NAT_ENTRY_PER_BLOCK) {
347*59bfda1fSAndroid Build Coastguard Worker 		block_off = nid / NAT_ENTRY_PER_BLOCK;
348*59bfda1fSAndroid Build Coastguard Worker 		seg_off = block_off >> sbi->log_blocks_per_seg;
349*59bfda1fSAndroid Build Coastguard Worker 		block_addr = (pgoff_t)(old_nat_blkaddr +
350*59bfda1fSAndroid Build Coastguard Worker 				(seg_off << sbi->log_blocks_per_seg << 1) +
351*59bfda1fSAndroid Build Coastguard Worker 				(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
352*59bfda1fSAndroid Build Coastguard Worker 
353*59bfda1fSAndroid Build Coastguard Worker 		/* move to set #0 */
354*59bfda1fSAndroid Build Coastguard Worker 		if (f2fs_test_bit(block_off, nm_i->nat_bitmap)) {
355*59bfda1fSAndroid Build Coastguard Worker 			block_addr += sbi->blocks_per_seg;
356*59bfda1fSAndroid Build Coastguard Worker 			f2fs_clear_bit(block_off, nm_i->nat_bitmap);
357*59bfda1fSAndroid Build Coastguard Worker 		}
358*59bfda1fSAndroid Build Coastguard Worker 
359*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_read_block(nat_block, block_addr);
360*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
361*59bfda1fSAndroid Build Coastguard Worker 
362*59bfda1fSAndroid Build Coastguard Worker 		block_addr = (pgoff_t)(new_nat_blkaddr +
363*59bfda1fSAndroid Build Coastguard Worker 				(seg_off << sbi->log_blocks_per_seg << 1) +
364*59bfda1fSAndroid Build Coastguard Worker 				(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
365*59bfda1fSAndroid Build Coastguard Worker 
366*59bfda1fSAndroid Build Coastguard Worker 		/* new bitmap should be zeros */
367*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(nat_block, block_addr, WRITE_LIFE_NONE);
368*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
369*59bfda1fSAndroid Build Coastguard Worker 	}
370*59bfda1fSAndroid Build Coastguard Worker 	/* zero out newly assigned nids */
371*59bfda1fSAndroid Build Coastguard Worker 	memset(nat_block, 0, F2FS_BLKSIZE);
372*59bfda1fSAndroid Build Coastguard Worker 	nat_blocks = get_newsb(segment_count_nat) >> 1;
373*59bfda1fSAndroid Build Coastguard Worker 	nat_blocks = nat_blocks << get_sb(log_blocks_per_seg);
374*59bfda1fSAndroid Build Coastguard Worker 	new_max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks;
375*59bfda1fSAndroid Build Coastguard Worker 
376*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "Write NAT block: %x->%x, max_nid=%x->%x\n",
377*59bfda1fSAndroid Build Coastguard Worker 			old_nat_blkaddr, new_nat_blkaddr,
378*59bfda1fSAndroid Build Coastguard Worker 			get_sb(segment_count_nat),
379*59bfda1fSAndroid Build Coastguard Worker 			get_newsb(segment_count_nat));
380*59bfda1fSAndroid Build Coastguard Worker 
381*59bfda1fSAndroid Build Coastguard Worker 	for (nid = nm_i->max_nid; nid < new_max_nid;
382*59bfda1fSAndroid Build Coastguard Worker 				nid += NAT_ENTRY_PER_BLOCK) {
383*59bfda1fSAndroid Build Coastguard Worker 		block_off = nid / NAT_ENTRY_PER_BLOCK;
384*59bfda1fSAndroid Build Coastguard Worker 		seg_off = block_off >> sbi->log_blocks_per_seg;
385*59bfda1fSAndroid Build Coastguard Worker 		block_addr = (pgoff_t)(new_nat_blkaddr +
386*59bfda1fSAndroid Build Coastguard Worker 				(seg_off << sbi->log_blocks_per_seg << 1) +
387*59bfda1fSAndroid Build Coastguard Worker 				(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
388*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(nat_block, block_addr, WRITE_LIFE_NONE);
389*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
390*59bfda1fSAndroid Build Coastguard Worker 		DBG(3, "Write NAT: %lx\n", block_addr);
391*59bfda1fSAndroid Build Coastguard Worker 	}
392*59bfda1fSAndroid Build Coastguard Worker 	free(nat_block);
393*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Done to migrate NAT blocks: nat_blkaddr = 0x%x -> 0x%x\n",
394*59bfda1fSAndroid Build Coastguard Worker 			old_nat_blkaddr, new_nat_blkaddr);
395*59bfda1fSAndroid Build Coastguard Worker }
396*59bfda1fSAndroid Build Coastguard Worker 
migrate_sit(struct f2fs_sb_info * sbi,struct f2fs_super_block * new_sb,unsigned int offset)397*59bfda1fSAndroid Build Coastguard Worker static void migrate_sit(struct f2fs_sb_info *sbi,
398*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_super_block *new_sb, unsigned int offset)
399*59bfda1fSAndroid Build Coastguard Worker {
400*59bfda1fSAndroid Build Coastguard Worker 	struct sit_info *sit_i = SIT_I(sbi);
401*59bfda1fSAndroid Build Coastguard Worker 	unsigned int ofs = 0, pre_ofs = 0;
402*59bfda1fSAndroid Build Coastguard Worker 	unsigned int segno, index;
403*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_sit_block *sit_blk = calloc(F2FS_BLKSIZE, 1);
404*59bfda1fSAndroid Build Coastguard Worker 	block_t sit_blks = get_newsb(segment_count_sit) <<
405*59bfda1fSAndroid Build Coastguard Worker 						(sbi->log_blocks_per_seg - 1);
406*59bfda1fSAndroid Build Coastguard Worker 	struct seg_entry *se;
407*59bfda1fSAndroid Build Coastguard Worker 	block_t blk_addr = 0;
408*59bfda1fSAndroid Build Coastguard Worker 	int ret;
409*59bfda1fSAndroid Build Coastguard Worker 
410*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(sit_blk);
411*59bfda1fSAndroid Build Coastguard Worker 
412*59bfda1fSAndroid Build Coastguard Worker 	/* initialize with zeros */
413*59bfda1fSAndroid Build Coastguard Worker 	for (index = 0; index < sit_blks; index++) {
414*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(sit_blk, get_newsb(sit_blkaddr) + index,
415*59bfda1fSAndroid Build Coastguard Worker 				      WRITE_LIFE_NONE);
416*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
417*59bfda1fSAndroid Build Coastguard Worker 		DBG(3, "Write zero sit: %x\n", get_newsb(sit_blkaddr) + index);
418*59bfda1fSAndroid Build Coastguard Worker 	}
419*59bfda1fSAndroid Build Coastguard Worker 
420*59bfda1fSAndroid Build Coastguard Worker 	for (segno = 0; segno < MAIN_SEGS(sbi); segno++) {
421*59bfda1fSAndroid Build Coastguard Worker 		struct f2fs_sit_entry *sit;
422*59bfda1fSAndroid Build Coastguard Worker 
423*59bfda1fSAndroid Build Coastguard Worker 		se = get_seg_entry(sbi, segno);
424*59bfda1fSAndroid Build Coastguard Worker 		if (segno < offset) {
425*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(se->valid_blocks == 0);
426*59bfda1fSAndroid Build Coastguard Worker 			continue;
427*59bfda1fSAndroid Build Coastguard Worker 		}
428*59bfda1fSAndroid Build Coastguard Worker 
429*59bfda1fSAndroid Build Coastguard Worker 		ofs = SIT_BLOCK_OFFSET(sit_i, segno - offset);
430*59bfda1fSAndroid Build Coastguard Worker 
431*59bfda1fSAndroid Build Coastguard Worker 		if (ofs != pre_ofs) {
432*59bfda1fSAndroid Build Coastguard Worker 			blk_addr = get_newsb(sit_blkaddr) + pre_ofs;
433*59bfda1fSAndroid Build Coastguard Worker 			ret = dev_write_block(sit_blk, blk_addr,
434*59bfda1fSAndroid Build Coastguard Worker 					      WRITE_LIFE_NONE);
435*59bfda1fSAndroid Build Coastguard Worker 			ASSERT(ret >= 0);
436*59bfda1fSAndroid Build Coastguard Worker 			DBG(1, "Write valid sit: %x\n", blk_addr);
437*59bfda1fSAndroid Build Coastguard Worker 
438*59bfda1fSAndroid Build Coastguard Worker 			pre_ofs = ofs;
439*59bfda1fSAndroid Build Coastguard Worker 			memset(sit_blk, 0, F2FS_BLKSIZE);
440*59bfda1fSAndroid Build Coastguard Worker 		}
441*59bfda1fSAndroid Build Coastguard Worker 
442*59bfda1fSAndroid Build Coastguard Worker 		sit = &sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, segno - offset)];
443*59bfda1fSAndroid Build Coastguard Worker 		memcpy(sit->valid_map, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
444*59bfda1fSAndroid Build Coastguard Worker 		sit->vblocks = cpu_to_le16((se->type << SIT_VBLOCKS_SHIFT) |
445*59bfda1fSAndroid Build Coastguard Worker 							se->valid_blocks);
446*59bfda1fSAndroid Build Coastguard Worker 	}
447*59bfda1fSAndroid Build Coastguard Worker 	blk_addr = get_newsb(sit_blkaddr) + ofs;
448*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_write_block(sit_blk, blk_addr, WRITE_LIFE_NONE);
449*59bfda1fSAndroid Build Coastguard Worker 	DBG(1, "Write valid sit: %x\n", blk_addr);
450*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
451*59bfda1fSAndroid Build Coastguard Worker 
452*59bfda1fSAndroid Build Coastguard Worker 	free(sit_blk);
453*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Done to restore new SIT blocks: 0x%x\n",
454*59bfda1fSAndroid Build Coastguard Worker 					get_newsb(sit_blkaddr));
455*59bfda1fSAndroid Build Coastguard Worker }
456*59bfda1fSAndroid Build Coastguard Worker 
rebuild_checkpoint(struct f2fs_sb_info * sbi,struct f2fs_super_block * new_sb,unsigned int offset)457*59bfda1fSAndroid Build Coastguard Worker static void rebuild_checkpoint(struct f2fs_sb_info *sbi,
458*59bfda1fSAndroid Build Coastguard Worker 			struct f2fs_super_block *new_sb, unsigned int offset)
459*59bfda1fSAndroid Build Coastguard Worker {
460*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
461*59bfda1fSAndroid Build Coastguard Worker 	unsigned long long cp_ver = get_cp(checkpoint_ver);
462*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_checkpoint *new_cp;
463*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
464*59bfda1fSAndroid Build Coastguard Worker 	unsigned int free_segment_count, new_segment_count;
465*59bfda1fSAndroid Build Coastguard Worker 	block_t new_cp_blks = 1 + get_newsb(cp_payload);
466*59bfda1fSAndroid Build Coastguard Worker 	block_t orphan_blks = 0;
467*59bfda1fSAndroid Build Coastguard Worker 	block_t new_cp_blk_no, old_cp_blk_no;
468*59bfda1fSAndroid Build Coastguard Worker 	uint32_t crc = 0;
469*59bfda1fSAndroid Build Coastguard Worker 	u32 flags;
470*59bfda1fSAndroid Build Coastguard Worker 	void *buf;
471*59bfda1fSAndroid Build Coastguard Worker 	int i, ret;
472*59bfda1fSAndroid Build Coastguard Worker 
473*59bfda1fSAndroid Build Coastguard Worker 	new_cp = calloc(new_cp_blks * F2FS_BLKSIZE, 1);
474*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(new_cp);
475*59bfda1fSAndroid Build Coastguard Worker 
476*59bfda1fSAndroid Build Coastguard Worker 	buf = malloc(F2FS_BLKSIZE);
477*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(buf);
478*59bfda1fSAndroid Build Coastguard Worker 
479*59bfda1fSAndroid Build Coastguard Worker 	/* ovp / free segments */
480*59bfda1fSAndroid Build Coastguard Worker 	set_cp(rsvd_segment_count, c.new_reserved_segments);
481*59bfda1fSAndroid Build Coastguard Worker 	set_cp(overprov_segment_count, (get_newsb(segment_count_main) -
482*59bfda1fSAndroid Build Coastguard Worker 			get_cp(rsvd_segment_count)) *
483*59bfda1fSAndroid Build Coastguard Worker 			c.new_overprovision / 100);
484*59bfda1fSAndroid Build Coastguard Worker 
485*59bfda1fSAndroid Build Coastguard Worker 	/* give 2 sections (DATA and NODE) to trigger GC in advance */
486*59bfda1fSAndroid Build Coastguard Worker 	if (get_cp(overprov_segment_count) < get_cp(rsvd_segment_count))
487*59bfda1fSAndroid Build Coastguard Worker 		set_cp(overprov_segment_count, get_cp(rsvd_segment_count));
488*59bfda1fSAndroid Build Coastguard Worker 
489*59bfda1fSAndroid Build Coastguard Worker 	set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
490*59bfda1fSAndroid Build Coastguard Worker 						2 * get_sb(segs_per_sec));
491*59bfda1fSAndroid Build Coastguard Worker 
492*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Overprovision ratio = %.3lf%%\n", c.new_overprovision);
493*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Overprovision segments = %u (GC reserved = %u)\n",
494*59bfda1fSAndroid Build Coastguard Worker 					get_cp(overprov_segment_count),
495*59bfda1fSAndroid Build Coastguard Worker 					c.new_reserved_segments);
496*59bfda1fSAndroid Build Coastguard Worker 
497*59bfda1fSAndroid Build Coastguard Worker 	free_segment_count = get_free_segments(sbi);
498*59bfda1fSAndroid Build Coastguard Worker 	new_segment_count = get_newsb(segment_count_main) -
499*59bfda1fSAndroid Build Coastguard Worker 					get_sb(segment_count_main);
500*59bfda1fSAndroid Build Coastguard Worker 
501*59bfda1fSAndroid Build Coastguard Worker 	set_cp(free_segment_count, free_segment_count + new_segment_count);
502*59bfda1fSAndroid Build Coastguard Worker 	set_cp(user_block_count, ((get_newsb(segment_count_main) -
503*59bfda1fSAndroid Build Coastguard Worker 			get_cp(overprov_segment_count)) * c.blks_per_seg));
504*59bfda1fSAndroid Build Coastguard Worker 
505*59bfda1fSAndroid Build Coastguard Worker 	if (is_set_ckpt_flags(cp, CP_ORPHAN_PRESENT_FLAG))
506*59bfda1fSAndroid Build Coastguard Worker 		orphan_blks = __start_sum_addr(sbi) - 1;
507*59bfda1fSAndroid Build Coastguard Worker 
508*59bfda1fSAndroid Build Coastguard Worker 	set_cp(cp_pack_start_sum, 1 + get_newsb(cp_payload));
509*59bfda1fSAndroid Build Coastguard Worker 	set_cp(cp_pack_total_block_count, 8 + orphan_blks + get_newsb(cp_payload));
510*59bfda1fSAndroid Build Coastguard Worker 
511*59bfda1fSAndroid Build Coastguard Worker 	/* cur->segno - offset */
512*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < NO_CHECK_TYPE; i++) {
513*59bfda1fSAndroid Build Coastguard Worker 		if (i < CURSEG_HOT_NODE) {
514*59bfda1fSAndroid Build Coastguard Worker 			set_cp(cur_data_segno[i],
515*59bfda1fSAndroid Build Coastguard Worker 					CURSEG_I(sbi, i)->segno - offset);
516*59bfda1fSAndroid Build Coastguard Worker 		} else {
517*59bfda1fSAndroid Build Coastguard Worker 			int n = i - CURSEG_HOT_NODE;
518*59bfda1fSAndroid Build Coastguard Worker 
519*59bfda1fSAndroid Build Coastguard Worker 			set_cp(cur_node_segno[n],
520*59bfda1fSAndroid Build Coastguard Worker 					CURSEG_I(sbi, i)->segno - offset);
521*59bfda1fSAndroid Build Coastguard Worker 		}
522*59bfda1fSAndroid Build Coastguard Worker 	}
523*59bfda1fSAndroid Build Coastguard Worker 
524*59bfda1fSAndroid Build Coastguard Worker 	/* sit / nat ver bitmap bytesize */
525*59bfda1fSAndroid Build Coastguard Worker 	set_cp(sit_ver_bitmap_bytesize,
526*59bfda1fSAndroid Build Coastguard Worker 			((get_newsb(segment_count_sit) / 2) <<
527*59bfda1fSAndroid Build Coastguard Worker 			get_newsb(log_blocks_per_seg)) / 8);
528*59bfda1fSAndroid Build Coastguard Worker 	set_cp(nat_ver_bitmap_bytesize,
529*59bfda1fSAndroid Build Coastguard Worker 			((get_newsb(segment_count_nat) / 2) <<
530*59bfda1fSAndroid Build Coastguard Worker 			get_newsb(log_blocks_per_seg)) / 8);
531*59bfda1fSAndroid Build Coastguard Worker 
532*59bfda1fSAndroid Build Coastguard Worker 	/* update nat_bits flag */
533*59bfda1fSAndroid Build Coastguard Worker 	flags = update_nat_bits_flags(new_sb, cp, get_cp(ckpt_flags));
534*59bfda1fSAndroid Build Coastguard Worker 	if (c.large_nat_bitmap)
535*59bfda1fSAndroid Build Coastguard Worker 		flags |= CP_LARGE_NAT_BITMAP_FLAG;
536*59bfda1fSAndroid Build Coastguard Worker 
537*59bfda1fSAndroid Build Coastguard Worker 	if (flags & CP_COMPACT_SUM_FLAG)
538*59bfda1fSAndroid Build Coastguard Worker 		flags &= ~CP_COMPACT_SUM_FLAG;
539*59bfda1fSAndroid Build Coastguard Worker 	if (flags & CP_LARGE_NAT_BITMAP_FLAG)
540*59bfda1fSAndroid Build Coastguard Worker 		set_cp(checksum_offset, CP_MIN_CHKSUM_OFFSET);
541*59bfda1fSAndroid Build Coastguard Worker 	else
542*59bfda1fSAndroid Build Coastguard Worker 		set_cp(checksum_offset, CP_CHKSUM_OFFSET);
543*59bfda1fSAndroid Build Coastguard Worker 
544*59bfda1fSAndroid Build Coastguard Worker 	set_cp(ckpt_flags, flags);
545*59bfda1fSAndroid Build Coastguard Worker 
546*59bfda1fSAndroid Build Coastguard Worker 	memcpy(new_cp, cp, (unsigned char *)cp->sit_nat_version_bitmap -
547*59bfda1fSAndroid Build Coastguard Worker 						(unsigned char *)cp);
548*59bfda1fSAndroid Build Coastguard Worker 	if (c.safe_resize)
549*59bfda1fSAndroid Build Coastguard Worker 		memcpy((void *)new_cp + CP_BITMAP_OFFSET,
550*59bfda1fSAndroid Build Coastguard Worker 			(void *)cp + CP_BITMAP_OFFSET,
551*59bfda1fSAndroid Build Coastguard Worker 			F2FS_BLKSIZE - CP_BITMAP_OFFSET);
552*59bfda1fSAndroid Build Coastguard Worker 
553*59bfda1fSAndroid Build Coastguard Worker 	new_cp->checkpoint_ver = cpu_to_le64(cp_ver + 1);
554*59bfda1fSAndroid Build Coastguard Worker 
555*59bfda1fSAndroid Build Coastguard Worker 	crc = f2fs_checkpoint_chksum(new_cp);
556*59bfda1fSAndroid Build Coastguard Worker 	*((__le32 *)((unsigned char *)new_cp + get_cp(checksum_offset))) =
557*59bfda1fSAndroid Build Coastguard Worker 							cpu_to_le32(crc);
558*59bfda1fSAndroid Build Coastguard Worker 
559*59bfda1fSAndroid Build Coastguard Worker 	/* Write a new checkpoint in the other set */
560*59bfda1fSAndroid Build Coastguard Worker 	new_cp_blk_no = old_cp_blk_no = get_sb(cp_blkaddr);
561*59bfda1fSAndroid Build Coastguard Worker 	if (sbi->cur_cp == 2)
562*59bfda1fSAndroid Build Coastguard Worker 		old_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
563*59bfda1fSAndroid Build Coastguard Worker 	else
564*59bfda1fSAndroid Build Coastguard Worker 		new_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
565*59bfda1fSAndroid Build Coastguard Worker 
566*59bfda1fSAndroid Build Coastguard Worker 	/* write first cp */
567*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_write_block(new_cp, new_cp_blk_no++, WRITE_LIFE_NONE);
568*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
569*59bfda1fSAndroid Build Coastguard Worker 
570*59bfda1fSAndroid Build Coastguard Worker 	memset(buf, 0, F2FS_BLKSIZE);
571*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < get_newsb(cp_payload); i++) {
572*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(buf, new_cp_blk_no++, WRITE_LIFE_NONE);
573*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
574*59bfda1fSAndroid Build Coastguard Worker 	}
575*59bfda1fSAndroid Build Coastguard Worker 
576*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < orphan_blks; i++) {
577*59bfda1fSAndroid Build Coastguard Worker 		block_t orphan_blk_no = old_cp_blk_no + 1 + get_sb(cp_payload);
578*59bfda1fSAndroid Build Coastguard Worker 
579*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_read_block(buf, orphan_blk_no++);
580*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
581*59bfda1fSAndroid Build Coastguard Worker 
582*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(buf, new_cp_blk_no++, WRITE_LIFE_NONE);
583*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
584*59bfda1fSAndroid Build Coastguard Worker 	}
585*59bfda1fSAndroid Build Coastguard Worker 
586*59bfda1fSAndroid Build Coastguard Worker 	/* update summary blocks having nullified journal entries */
587*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < NO_CHECK_TYPE; i++) {
588*59bfda1fSAndroid Build Coastguard Worker 		struct curseg_info *curseg = CURSEG_I(sbi, i);
589*59bfda1fSAndroid Build Coastguard Worker 
590*59bfda1fSAndroid Build Coastguard Worker 		ret = dev_write_block(curseg->sum_blk, new_cp_blk_no++,
591*59bfda1fSAndroid Build Coastguard Worker 				      WRITE_LIFE_NONE);
592*59bfda1fSAndroid Build Coastguard Worker 		ASSERT(ret >= 0);
593*59bfda1fSAndroid Build Coastguard Worker 	}
594*59bfda1fSAndroid Build Coastguard Worker 
595*59bfda1fSAndroid Build Coastguard Worker 	/* write the last cp */
596*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_write_block(new_cp, new_cp_blk_no++, WRITE_LIFE_NONE);
597*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
598*59bfda1fSAndroid Build Coastguard Worker 
599*59bfda1fSAndroid Build Coastguard Worker 	/* Write nat bits */
600*59bfda1fSAndroid Build Coastguard Worker 	if (flags & CP_NAT_BITS_FLAG)
601*59bfda1fSAndroid Build Coastguard Worker 		write_nat_bits(sbi, new_sb, new_cp, sbi->cur_cp == 1 ? 2 : 1);
602*59bfda1fSAndroid Build Coastguard Worker 
603*59bfda1fSAndroid Build Coastguard Worker 	/* disable old checkpoint */
604*59bfda1fSAndroid Build Coastguard Worker 	memset(buf, 0, F2FS_BLKSIZE);
605*59bfda1fSAndroid Build Coastguard Worker 	ret = dev_write_block(buf, old_cp_blk_no, WRITE_LIFE_NONE);
606*59bfda1fSAndroid Build Coastguard Worker 	ASSERT(ret >= 0);
607*59bfda1fSAndroid Build Coastguard Worker 
608*59bfda1fSAndroid Build Coastguard Worker 	free(buf);
609*59bfda1fSAndroid Build Coastguard Worker 	free(new_cp);
610*59bfda1fSAndroid Build Coastguard Worker 	DBG(0, "Info: Done to rebuild checkpoint blocks\n");
611*59bfda1fSAndroid Build Coastguard Worker }
612*59bfda1fSAndroid Build Coastguard Worker 
f2fs_resize_check(struct f2fs_sb_info * sbi,struct f2fs_super_block * new_sb)613*59bfda1fSAndroid Build Coastguard Worker static int f2fs_resize_check(struct f2fs_sb_info *sbi, struct f2fs_super_block *new_sb)
614*59bfda1fSAndroid Build Coastguard Worker {
615*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
616*59bfda1fSAndroid Build Coastguard Worker 	block_t user_block_count;
617*59bfda1fSAndroid Build Coastguard Worker 	unsigned int overprov_segment_count;
618*59bfda1fSAndroid Build Coastguard Worker 
619*59bfda1fSAndroid Build Coastguard Worker 	overprov_segment_count = (get_newsb(segment_count_main) -
620*59bfda1fSAndroid Build Coastguard Worker 			c.new_reserved_segments) *
621*59bfda1fSAndroid Build Coastguard Worker 			c.new_overprovision / 100;
622*59bfda1fSAndroid Build Coastguard Worker 
623*59bfda1fSAndroid Build Coastguard Worker 	overprov_segment_count += 2 * get_newsb(segs_per_sec);
624*59bfda1fSAndroid Build Coastguard Worker 
625*59bfda1fSAndroid Build Coastguard Worker 	user_block_count = (get_newsb(segment_count_main) -
626*59bfda1fSAndroid Build Coastguard Worker 			overprov_segment_count) * c.blks_per_seg;
627*59bfda1fSAndroid Build Coastguard Worker 
628*59bfda1fSAndroid Build Coastguard Worker 	if (get_cp(valid_block_count) > user_block_count)
629*59bfda1fSAndroid Build Coastguard Worker 		return -1;
630*59bfda1fSAndroid Build Coastguard Worker 
631*59bfda1fSAndroid Build Coastguard Worker 	return 0;
632*59bfda1fSAndroid Build Coastguard Worker }
633*59bfda1fSAndroid Build Coastguard Worker 
f2fs_resize_grow(struct f2fs_sb_info * sbi)634*59bfda1fSAndroid Build Coastguard Worker static int f2fs_resize_grow(struct f2fs_sb_info *sbi)
635*59bfda1fSAndroid Build Coastguard Worker {
636*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
637*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block new_sb_raw;
638*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *new_sb = &new_sb_raw;
639*59bfda1fSAndroid Build Coastguard Worker 	block_t end_blkaddr, old_main_blkaddr, new_main_blkaddr;
640*59bfda1fSAndroid Build Coastguard Worker 	unsigned int offset;
641*59bfda1fSAndroid Build Coastguard Worker 	unsigned int offset_seg = 0;
642*59bfda1fSAndroid Build Coastguard Worker 	int err = -1;
643*59bfda1fSAndroid Build Coastguard Worker 
644*59bfda1fSAndroid Build Coastguard Worker 	/* flush NAT/SIT journal entries */
645*59bfda1fSAndroid Build Coastguard Worker 	flush_journal_entries(sbi);
646*59bfda1fSAndroid Build Coastguard Worker 
647*59bfda1fSAndroid Build Coastguard Worker 	memcpy(new_sb, F2FS_RAW_SUPER(sbi), sizeof(*new_sb));
648*59bfda1fSAndroid Build Coastguard Worker 	if (get_new_sb(new_sb))
649*59bfda1fSAndroid Build Coastguard Worker 		return -1;
650*59bfda1fSAndroid Build Coastguard Worker 
651*59bfda1fSAndroid Build Coastguard Worker 	if (f2fs_resize_check(sbi, new_sb) < 0)
652*59bfda1fSAndroid Build Coastguard Worker 		return -1;
653*59bfda1fSAndroid Build Coastguard Worker 
654*59bfda1fSAndroid Build Coastguard Worker 	/* check nat availability */
655*59bfda1fSAndroid Build Coastguard Worker 	if (get_sb(segment_count_nat) > get_newsb(segment_count_nat)) {
656*59bfda1fSAndroid Build Coastguard Worker 		err = shrink_nats(sbi, new_sb);
657*59bfda1fSAndroid Build Coastguard Worker 		if (err) {
658*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "\tError: Failed to shrink NATs\n");
659*59bfda1fSAndroid Build Coastguard Worker 			return err;
660*59bfda1fSAndroid Build Coastguard Worker 		}
661*59bfda1fSAndroid Build Coastguard Worker 	}
662*59bfda1fSAndroid Build Coastguard Worker 
663*59bfda1fSAndroid Build Coastguard Worker 	old_main_blkaddr = get_sb(main_blkaddr);
664*59bfda1fSAndroid Build Coastguard Worker 	new_main_blkaddr = get_newsb(main_blkaddr);
665*59bfda1fSAndroid Build Coastguard Worker 	offset = new_main_blkaddr - old_main_blkaddr;
666*59bfda1fSAndroid Build Coastguard Worker 	end_blkaddr = (get_sb(segment_count_main) <<
667*59bfda1fSAndroid Build Coastguard Worker 			get_sb(log_blocks_per_seg)) + get_sb(main_blkaddr);
668*59bfda1fSAndroid Build Coastguard Worker 
669*59bfda1fSAndroid Build Coastguard Worker 	err = -EAGAIN;
670*59bfda1fSAndroid Build Coastguard Worker 	if (new_main_blkaddr < end_blkaddr) {
671*59bfda1fSAndroid Build Coastguard Worker 		err = f2fs_defragment(sbi, old_main_blkaddr, offset,
672*59bfda1fSAndroid Build Coastguard Worker 						new_main_blkaddr, 0);
673*59bfda1fSAndroid Build Coastguard Worker 		if (!err)
674*59bfda1fSAndroid Build Coastguard Worker 			offset_seg = offset >> get_sb(log_blocks_per_seg);
675*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Try to do defragement: %s\n", err ? "Skip": "Done");
676*59bfda1fSAndroid Build Coastguard Worker 	}
677*59bfda1fSAndroid Build Coastguard Worker 	/* move whole data region */
678*59bfda1fSAndroid Build Coastguard Worker 	if (err)
679*59bfda1fSAndroid Build Coastguard Worker 		migrate_main(sbi, offset);
680*59bfda1fSAndroid Build Coastguard Worker 
681*59bfda1fSAndroid Build Coastguard Worker 	migrate_ssa(sbi, new_sb, offset_seg);
682*59bfda1fSAndroid Build Coastguard Worker 	migrate_nat(sbi, new_sb);
683*59bfda1fSAndroid Build Coastguard Worker 	migrate_sit(sbi, new_sb, offset_seg);
684*59bfda1fSAndroid Build Coastguard Worker 	rebuild_checkpoint(sbi, new_sb, offset_seg);
685*59bfda1fSAndroid Build Coastguard Worker 	update_superblock(new_sb, SB_MASK_ALL);
686*59bfda1fSAndroid Build Coastguard Worker 	print_raw_sb_info(sb);
687*59bfda1fSAndroid Build Coastguard Worker 	print_raw_sb_info(new_sb);
688*59bfda1fSAndroid Build Coastguard Worker 
689*59bfda1fSAndroid Build Coastguard Worker 	return 0;
690*59bfda1fSAndroid Build Coastguard Worker }
691*59bfda1fSAndroid Build Coastguard Worker 
f2fs_resize_shrink(struct f2fs_sb_info * sbi)692*59bfda1fSAndroid Build Coastguard Worker static int f2fs_resize_shrink(struct f2fs_sb_info *sbi)
693*59bfda1fSAndroid Build Coastguard Worker {
694*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
695*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block new_sb_raw;
696*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *new_sb = &new_sb_raw;
697*59bfda1fSAndroid Build Coastguard Worker 	block_t old_end_blkaddr, old_main_blkaddr;
698*59bfda1fSAndroid Build Coastguard Worker 	block_t new_end_blkaddr, new_main_blkaddr, tmp_end_blkaddr;
699*59bfda1fSAndroid Build Coastguard Worker 	unsigned int offset;
700*59bfda1fSAndroid Build Coastguard Worker 	int err = -1;
701*59bfda1fSAndroid Build Coastguard Worker 
702*59bfda1fSAndroid Build Coastguard Worker 	/* flush NAT/SIT journal entries */
703*59bfda1fSAndroid Build Coastguard Worker 	flush_journal_entries(sbi);
704*59bfda1fSAndroid Build Coastguard Worker 
705*59bfda1fSAndroid Build Coastguard Worker 	memcpy(new_sb, F2FS_RAW_SUPER(sbi), sizeof(*new_sb));
706*59bfda1fSAndroid Build Coastguard Worker 	if (get_new_sb(new_sb))
707*59bfda1fSAndroid Build Coastguard Worker 		return -1;
708*59bfda1fSAndroid Build Coastguard Worker 
709*59bfda1fSAndroid Build Coastguard Worker 	if (f2fs_resize_check(sbi, new_sb) < 0)
710*59bfda1fSAndroid Build Coastguard Worker 		return -1;
711*59bfda1fSAndroid Build Coastguard Worker 
712*59bfda1fSAndroid Build Coastguard Worker 	/* check nat availability */
713*59bfda1fSAndroid Build Coastguard Worker 	if (get_sb(segment_count_nat) > get_newsb(segment_count_nat)) {
714*59bfda1fSAndroid Build Coastguard Worker 		err = shrink_nats(sbi, new_sb);
715*59bfda1fSAndroid Build Coastguard Worker 		if (err) {
716*59bfda1fSAndroid Build Coastguard Worker 			MSG(0, "\tError: Failed to shrink NATs\n");
717*59bfda1fSAndroid Build Coastguard Worker 			return err;
718*59bfda1fSAndroid Build Coastguard Worker 		}
719*59bfda1fSAndroid Build Coastguard Worker 	}
720*59bfda1fSAndroid Build Coastguard Worker 
721*59bfda1fSAndroid Build Coastguard Worker 	old_main_blkaddr = get_sb(main_blkaddr);
722*59bfda1fSAndroid Build Coastguard Worker 	new_main_blkaddr = get_newsb(main_blkaddr);
723*59bfda1fSAndroid Build Coastguard Worker 	offset = old_main_blkaddr - new_main_blkaddr;
724*59bfda1fSAndroid Build Coastguard Worker 	old_end_blkaddr = (get_sb(segment_count_main) <<
725*59bfda1fSAndroid Build Coastguard Worker 			get_sb(log_blocks_per_seg)) + get_sb(main_blkaddr);
726*59bfda1fSAndroid Build Coastguard Worker 	new_end_blkaddr = (get_newsb(segment_count_main) <<
727*59bfda1fSAndroid Build Coastguard Worker 			get_newsb(log_blocks_per_seg)) + get_newsb(main_blkaddr);
728*59bfda1fSAndroid Build Coastguard Worker 
729*59bfda1fSAndroid Build Coastguard Worker 	tmp_end_blkaddr = new_end_blkaddr + offset;
730*59bfda1fSAndroid Build Coastguard Worker 	err = f2fs_defragment(sbi, tmp_end_blkaddr,
731*59bfda1fSAndroid Build Coastguard Worker 				old_end_blkaddr - tmp_end_blkaddr,
732*59bfda1fSAndroid Build Coastguard Worker 				tmp_end_blkaddr, 1);
733*59bfda1fSAndroid Build Coastguard Worker 	MSG(0, "Try to do defragement: %s\n", err ? "Insufficient Space": "Done");
734*59bfda1fSAndroid Build Coastguard Worker 
735*59bfda1fSAndroid Build Coastguard Worker 	if (err) {
736*59bfda1fSAndroid Build Coastguard Worker 		return -ENOSPC;
737*59bfda1fSAndroid Build Coastguard Worker 	}
738*59bfda1fSAndroid Build Coastguard Worker 
739*59bfda1fSAndroid Build Coastguard Worker 	update_superblock(new_sb, SB_MASK_ALL);
740*59bfda1fSAndroid Build Coastguard Worker 	rebuild_checkpoint(sbi, new_sb, 0);
741*59bfda1fSAndroid Build Coastguard Worker 	/*if (!c.safe_resize) {
742*59bfda1fSAndroid Build Coastguard Worker 		migrate_sit(sbi, new_sb, offset_seg);
743*59bfda1fSAndroid Build Coastguard Worker 		migrate_nat(sbi, new_sb);
744*59bfda1fSAndroid Build Coastguard Worker 		migrate_ssa(sbi, new_sb, offset_seg);
745*59bfda1fSAndroid Build Coastguard Worker 	}*/
746*59bfda1fSAndroid Build Coastguard Worker 
747*59bfda1fSAndroid Build Coastguard Worker 	/* move whole data region */
748*59bfda1fSAndroid Build Coastguard Worker 	//if (err)
749*59bfda1fSAndroid Build Coastguard Worker 	//	migrate_main(sbi, offset);
750*59bfda1fSAndroid Build Coastguard Worker 	print_raw_sb_info(sb);
751*59bfda1fSAndroid Build Coastguard Worker 	print_raw_sb_info(new_sb);
752*59bfda1fSAndroid Build Coastguard Worker 
753*59bfda1fSAndroid Build Coastguard Worker 	return 0;
754*59bfda1fSAndroid Build Coastguard Worker }
755*59bfda1fSAndroid Build Coastguard Worker 
f2fs_resize(struct f2fs_sb_info * sbi)756*59bfda1fSAndroid Build Coastguard Worker int f2fs_resize(struct f2fs_sb_info *sbi)
757*59bfda1fSAndroid Build Coastguard Worker {
758*59bfda1fSAndroid Build Coastguard Worker 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
759*59bfda1fSAndroid Build Coastguard Worker 
760*59bfda1fSAndroid Build Coastguard Worker 	/* may different sector size */
761*59bfda1fSAndroid Build Coastguard Worker 	if ((c.target_sectors * c.sector_size >>
762*59bfda1fSAndroid Build Coastguard Worker 			get_sb(log_blocksize)) < get_sb(block_count))
763*59bfda1fSAndroid Build Coastguard Worker 		if (!c.safe_resize) {
764*59bfda1fSAndroid Build Coastguard Worker 			ASSERT_MSG("Nothing to resize, now only supports resizing with safe resize flag\n");
765*59bfda1fSAndroid Build Coastguard Worker 			return -1;
766*59bfda1fSAndroid Build Coastguard Worker 		} else {
767*59bfda1fSAndroid Build Coastguard Worker 			return f2fs_resize_shrink(sbi);
768*59bfda1fSAndroid Build Coastguard Worker 		}
769*59bfda1fSAndroid Build Coastguard Worker 	else if (((c.target_sectors * c.sector_size >>
770*59bfda1fSAndroid Build Coastguard Worker 			get_sb(log_blocksize)) > get_sb(block_count)) ||
771*59bfda1fSAndroid Build Coastguard Worker 			c.force)
772*59bfda1fSAndroid Build Coastguard Worker 		return f2fs_resize_grow(sbi);
773*59bfda1fSAndroid Build Coastguard Worker 	else {
774*59bfda1fSAndroid Build Coastguard Worker 		MSG(0, "Nothing to resize.\n");
775*59bfda1fSAndroid Build Coastguard Worker 		return 0;
776*59bfda1fSAndroid Build Coastguard Worker 	}
777*59bfda1fSAndroid Build Coastguard Worker }
778