xref: /aosp_15_r20/external/f2fs-tools/fsck/node.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1 /**
2  * node.c
3  *
4  * Many parts of codes are copied from Linux kernel/fs/f2fs.
5  *
6  * Copyright (C) 2015 Huawei Ltd.
7  * Witten by:
8  *   Hou Pengyang <[email protected]>
9  *   Liu Shuoran <[email protected]>
10  *   Jaegeuk Kim <[email protected]>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16 #include "fsck.h"
17 #include "node.h"
18 
f2fs_alloc_nid(struct f2fs_sb_info * sbi,nid_t * nid)19 void f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
20 {
21 	struct f2fs_nm_info *nm_i = NM_I(sbi);
22 	nid_t i;
23 
24 	for (i = 0; i < nm_i->max_nid; i++)
25 		if(f2fs_test_bit(i, nm_i->nid_bitmap) == 0)
26 			break;
27 
28 	ASSERT(i < nm_i->max_nid);
29 	f2fs_set_bit(i, nm_i->nid_bitmap);
30 	*nid = i;
31 }
32 
f2fs_release_nid(struct f2fs_sb_info * sbi,nid_t nid)33 void f2fs_release_nid(struct f2fs_sb_info *sbi, nid_t nid)
34 {
35 	struct f2fs_nm_info *nm_i = NM_I(sbi);
36 
37 	ASSERT(nid < nm_i->max_nid);
38 	ASSERT(f2fs_test_bit(nid, nm_i->nid_bitmap));
39 
40 	f2fs_clear_bit(nid, nm_i->nid_bitmap);
41 }
42 
f2fs_rebuild_qf_inode(struct f2fs_sb_info * sbi,int qtype)43 int f2fs_rebuild_qf_inode(struct f2fs_sb_info *sbi, int qtype)
44 {
45 	struct f2fs_node *raw_node = NULL;
46 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
47 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
48 	struct f2fs_summary sum;
49 	struct node_info ni;
50 	nid_t ino = QUOTA_INO(sb, qtype);
51 	block_t blkaddr = NULL_ADDR;
52 	__u64 cp_ver = cur_cp_version(ckpt);
53 	int ret = 0;
54 
55 	raw_node = calloc(F2FS_BLKSIZE, 1);
56 	if (raw_node == NULL) {
57 		MSG(1, "\tError: Calloc Failed for raw_node!!!\n");
58 		return -ENOMEM;
59 	}
60 	f2fs_init_inode(sb, raw_node,
61 			le32_to_cpu(sb->qf_ino[qtype]), time(NULL), 0x8180);
62 
63 	raw_node->i.i_size = cpu_to_le64(1024 * 6);
64 	raw_node->i.i_blocks = cpu_to_le64(1);
65 	raw_node->i.i_flags = cpu_to_le32(F2FS_NOATIME_FL | F2FS_IMMUTABLE_FL);
66 
67 	if (is_set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG))
68 		cp_ver |= (cur_cp_crc(ckpt) << 32);
69 	F2FS_NODE_FOOTER(raw_node)->cp_ver = cpu_to_le64(cp_ver);
70 
71 	get_node_info(sbi, ino, &ni);
72 	if (ni.ino != ino)
73 		ni.version = 0;
74 	set_summary(&sum, ino, 0, ni.version);
75 	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
76 	if (ret) {
77 		MSG(1, "\tError: Failed to reserve new block!\n");
78 		goto err_out;
79 	}
80 
81 	ret = write_inode(raw_node, blkaddr, f2fs_io_type_to_rw_hint(CURSEG_HOT_NODE));
82 	if (ret < 0) {
83 		MSG(1, "\tError: While rebuilding the quota inode to disk!\n");
84 		goto err_out;
85 	}
86 	update_nat_blkaddr(sbi, ino, ino, blkaddr);
87 
88 	f2fs_clear_bit(ino, F2FS_FSCK(sbi)->nat_area_bitmap);
89 	f2fs_set_bit(ino, NM_I(sbi)->nid_bitmap);
90 	DBG(1, "Rebuild quota inode ([%3d] ino [0x%x]) at offset:0x%x\n",
91 						qtype, ino, blkaddr);
92 err_out:
93 	free(raw_node);
94 	return ret;
95 }
96 
set_data_blkaddr(struct dnode_of_data * dn)97 void set_data_blkaddr(struct dnode_of_data *dn)
98 {
99 	__le32 *addr_array;
100 	struct f2fs_node *node_blk = dn->node_blk;
101 	unsigned int ofs_in_node = dn->ofs_in_node;
102 
103 	addr_array = blkaddr_in_node(node_blk);
104 	addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
105 	if (dn->node_blk != dn->inode_blk)
106 		dn->ndirty = 1;
107 	else
108 		dn->idirty = 1;
109 }
110 
111 /*
112  * In this function, we get a new node blk, and write back
113  * node_blk would be sloadd in RAM, linked by dn->node_blk
114  */
new_node_block(struct f2fs_sb_info * sbi,struct dnode_of_data * dn,unsigned int ofs)115 block_t new_node_block(struct f2fs_sb_info *sbi,
116 				struct dnode_of_data *dn, unsigned int ofs)
117 {
118 	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
119 	struct f2fs_node *f2fs_inode;
120 	struct f2fs_node *node_blk;
121 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
122 	struct f2fs_summary sum;
123 	struct node_info ni;
124 	block_t blkaddr = NULL_ADDR;
125 	int type;
126 	int ret;
127 
128 	f2fs_inode = dn->inode_blk;
129 
130 	node_blk = calloc(F2FS_BLKSIZE, 1);
131 	ASSERT(node_blk);
132 
133 	F2FS_NODE_FOOTER(node_blk)->nid = cpu_to_le32(dn->nid);
134 	F2FS_NODE_FOOTER(node_blk)->ino = F2FS_NODE_FOOTER(f2fs_inode)->ino;
135 	F2FS_NODE_FOOTER(node_blk)->flag = cpu_to_le32(ofs << OFFSET_BIT_SHIFT);
136 	F2FS_NODE_FOOTER(node_blk)->cp_ver = ckpt->checkpoint_ver;
137 	set_cold_node(node_blk, S_ISDIR(le16_to_cpu(f2fs_inode->i.i_mode)));
138 
139 	type = CURSEG_COLD_NODE;
140 	if (IS_DNODE(node_blk)) {
141 		if (S_ISDIR(le16_to_cpu(f2fs_inode->i.i_mode)))
142 			type = CURSEG_HOT_NODE;
143 		else
144 			type = CURSEG_WARM_NODE;
145 	}
146 
147 	if ((get_sb(feature) & F2FS_FEATURE_RO) &&
148 					type != CURSEG_HOT_NODE)
149 		type = CURSEG_HOT_NODE;
150 
151 	get_node_info(sbi, dn->nid, &ni);
152 	set_summary(&sum, dn->nid, 0, ni.version);
153 	ret = reserve_new_block(sbi, &blkaddr, &sum, type, !ofs);
154 	if (ret) {
155 		free(node_blk);
156 		return 0;
157 	}
158 
159 	/* update nat info */
160 	update_nat_blkaddr(sbi, le32_to_cpu(F2FS_NODE_FOOTER(f2fs_inode)->ino),
161 						dn->nid, blkaddr);
162 
163 	dn->node_blk = node_blk;
164 	inc_inode_blocks(dn);
165 	return blkaddr;
166 }
167 
168 /*
169  * get_node_path - Get the index path of pgoff_t block
170  * @offset: offset in the current index node block.
171  * @noffset: NO. of the index block within a file.
172  * return: depth of the index path.
173  *
174  * By default, it sets inline_xattr and inline_data
175  */
get_node_path(struct f2fs_node * node,long block,int offset[4],unsigned int noffset[4])176 static int get_node_path(struct f2fs_node *node, long block,
177 				int offset[4], unsigned int noffset[4])
178 {
179 	const long direct_index = ADDRS_PER_INODE(&node->i);
180 	const long direct_blks = ADDRS_PER_BLOCK(&node->i);
181 	const long dptrs_per_blk = NIDS_PER_BLOCK;
182 	const long indirect_blks = ADDRS_PER_BLOCK(&node->i) * NIDS_PER_BLOCK;
183 	const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK;
184 	int n = 0;
185 	int level = 0;
186 
187 	noffset[0] = 0;
188 	if (block < direct_index) {
189 		offset[n] = block;
190 		goto got;
191 	}
192 
193 	block -= direct_index;
194 	if (block < direct_blks) {
195 		offset[n++] = NODE_DIR1_BLOCK;
196 		noffset[n]= 1;
197 		offset[n] = block;
198 		level = 1;
199 		goto got;
200 	}
201 	block -= direct_blks;
202 	if (block < direct_blks) {
203 		offset[n++] = NODE_DIR2_BLOCK;
204 		noffset[n] = 2;
205 		offset[n] = block;
206 		level = 1;
207 		goto got;
208 	}
209 	block -= direct_blks;
210 	if (block < indirect_blks) {
211 		offset[n++] = NODE_IND1_BLOCK;
212 		noffset[n] = 3;
213 		offset[n++] = block / direct_blks;
214 		noffset[n] = 4 + offset[n - 1];
215 		offset[n] = block % direct_blks;
216 		level = 2;
217 		goto got;
218 	}
219 	block -= indirect_blks;
220 	if (block < indirect_blks) {
221 		offset[n++] = NODE_IND2_BLOCK;
222 		noffset[n] = 4 + dptrs_per_blk;
223 		offset[n++] = block / direct_blks;
224 		noffset[n] = 5 + dptrs_per_blk + offset[n - 1];
225 		offset[n] = block % direct_blks;
226 		level = 2;
227 		goto got;
228 	}
229 	block -= indirect_blks;
230 	if (block < dindirect_blks) {
231 		offset[n++] = NODE_DIND_BLOCK;
232 		noffset[n] = 5 + (dptrs_per_blk * 2);
233 		offset[n++] = block / indirect_blks;
234 		noffset[n] = 6 + (dptrs_per_blk * 2) +
235 			offset[n - 1] * (dptrs_per_blk + 1);
236 		offset[n++] = (block / direct_blks) % dptrs_per_blk;
237 		noffset[n] = 7 + (dptrs_per_blk * 2) +
238 			offset[n - 2] * (dptrs_per_blk + 1) +
239 			offset[n - 1];
240 		offset[n] = block % direct_blks;
241 		level = 3;
242 		goto got;
243 	} else {
244 		ASSERT(0);
245 	}
246 got:
247 	return level;
248 }
249 
get_dnode_of_data(struct f2fs_sb_info * sbi,struct dnode_of_data * dn,pgoff_t index,int mode)250 int get_dnode_of_data(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
251 						pgoff_t index, int mode)
252 {
253 	int offset[4];
254 	unsigned int noffset[4];
255 	struct f2fs_node *parent = NULL;
256 	nid_t nids[4];
257 	block_t nblk[4];
258 	struct node_info ni;
259 	int level, i;
260 	bool parent_alloced = false;
261 	int ret;
262 
263 	level = get_node_path(dn->inode_blk, index, offset, noffset);
264 
265 	nids[0] = dn->nid;
266 	parent = dn->inode_blk;
267 	if (level != 0)
268 		nids[1] = get_nid(parent, offset[0], 1);
269 	else
270 		dn->node_blk = dn->inode_blk;
271 
272 	get_node_info(sbi, nids[0], &ni);
273 	nblk[0] = ni.blk_addr;
274 
275 	for (i = 1; i <= level; i++) {
276 		if (!nids[i] && mode == ALLOC_NODE) {
277 			f2fs_alloc_nid(sbi, &nids[i]);
278 
279 			dn->nid = nids[i];
280 			set_nid(parent, offset[i - 1], nids[i], i == 1);
281 
282 			/* Parent node has changed */
283 			if (!parent_alloced)
284 				ret = update_block(sbi, parent, &nblk[i - 1], NULL);
285 			else {
286 				struct seg_entry *se;
287 
288 				se = get_seg_entry(sbi, GET_SEGNO(sbi, nblk[i - 1]));
289 				ret = dev_write_block(parent, nblk[i - 1],
290 						f2fs_io_type_to_rw_hint(se->type));
291 			}
292 			ASSERT(ret >= 0);
293 
294 			/* Function new_node_blk get a new f2fs_node blk and update*/
295 			/* We should make sure that dn->node_blk == NULL*/
296 			nblk[i] = new_node_block(sbi, dn, noffset[i]);
297 			if (!nblk[i]) {
298 				f2fs_release_nid(sbi, nids[i]);
299 				c.alloc_failed = 1;
300 				return -EINVAL;
301 			}
302 
303 			parent_alloced = true;
304 			if (i == level)
305 				dn->alloced = 1;
306 		} else {
307 			/* If Sparse file no read API, */
308 			struct node_info ni;
309 
310 			get_node_info(sbi, nids[i], &ni);
311 			dn->node_blk = calloc(F2FS_BLKSIZE, 1);
312 			ASSERT(dn->node_blk);
313 
314 			ret = dev_read_block(dn->node_blk, ni.blk_addr);
315 			ASSERT(ret >= 0);
316 
317 			nblk[i] = ni.blk_addr;
318 		}
319 
320 		if (i != 1)
321 			free(parent);
322 
323 		if (i < level) {
324 			parent = dn->node_blk;
325 			nids[i + 1] = get_nid(parent, offset[i], 0);
326 		}
327 	}
328 
329 	dn->nid = nids[level];
330 	dn->ofs_in_node = offset[level];
331 	dn->data_blkaddr = datablock_addr(dn->node_blk, dn->ofs_in_node);
332 	dn->node_blkaddr = nblk[level];
333 	return 0;
334 }
335 
update_inode(struct f2fs_sb_info * sbi,struct f2fs_node * inode,u32 * blkaddr)336 int update_inode(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
337 				u32 *blkaddr)
338 {
339 	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
340 		inode->i.i_inode_checksum =
341 			cpu_to_le32(f2fs_inode_chksum(inode));
342 	return update_block(sbi, inode, blkaddr, NULL);
343 }
344