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