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