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