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 <houpengyang@huawei.com>
9 * Liu Shuoran <liushuoran@huawei.com>
10 * Jaegeuk Kim <jaegeuk@kernel.org>
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_qf_inode(sb, raw_node, qtype, time(NULL));
61
62 if (is_set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG))
63 cp_ver |= (cur_cp_crc(ckpt) << 32);
64 raw_node->footer.cp_ver = cpu_to_le64(cp_ver);
65
66 get_node_info(sbi, ino, &ni);
67 set_summary(&sum, ino, 0, ni.version);
68 ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
69 if (ret) {
70 MSG(1, "\tError: Failed to reserve new block!\n");
71 goto err_out;
72 }
73
74 ret = write_inode(raw_node, blkaddr);
75 if (ret < 0) {
76 MSG(1, "\tError: While rebuilding the quota inode to disk!\n");
77 goto err_out;
78 }
79 update_nat_blkaddr(sbi, ino, ino, blkaddr);
80
81 f2fs_clear_bit(ino, F2FS_FSCK(sbi)->nat_area_bitmap);
82 f2fs_set_bit(ino, NM_I(sbi)->nid_bitmap);
83 DBG(1, "Rebuild quota inode ([%3d] ino [0x%x]) at offset:0x%x\n",
84 qtype, ino, blkaddr);
85 err_out:
86 free(raw_node);
87 return ret;
88 }
89
set_data_blkaddr(struct dnode_of_data * dn)90 void set_data_blkaddr(struct dnode_of_data *dn)
91 {
92 __le32 *addr_array;
93 struct f2fs_node *node_blk = dn->node_blk;
94 unsigned int ofs_in_node = dn->ofs_in_node;
95
96 addr_array = blkaddr_in_node(node_blk);
97 addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
98 if (dn->node_blk != dn->inode_blk)
99 dn->ndirty = 1;
100 else
101 dn->idirty = 1;
102 }
103
104 /*
105 * In this function, we get a new node blk, and write back
106 * node_blk would be sloadd in RAM, linked by dn->node_blk
107 */
new_node_block(struct f2fs_sb_info * sbi,struct dnode_of_data * dn,unsigned int ofs)108 block_t new_node_block(struct f2fs_sb_info *sbi,
109 struct dnode_of_data *dn, unsigned int ofs)
110 {
111 struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
112 struct f2fs_node *f2fs_inode;
113 struct f2fs_node *node_blk;
114 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
115 struct f2fs_summary sum;
116 struct node_info ni;
117 block_t blkaddr = NULL_ADDR;
118 int type;
119 int ret;
120
121 f2fs_inode = dn->inode_blk;
122
123 node_blk = calloc(BLOCK_SZ, 1);
124 ASSERT(node_blk);
125
126 node_blk->footer.nid = cpu_to_le32(dn->nid);
127 node_blk->footer.ino = f2fs_inode->footer.ino;
128 node_blk->footer.flag = cpu_to_le32(ofs << OFFSET_BIT_SHIFT);
129 node_blk->footer.cp_ver = ckpt->checkpoint_ver;
130 set_cold_node(node_blk, S_ISDIR(le16_to_cpu(f2fs_inode->i.i_mode)));
131
132 type = CURSEG_COLD_NODE;
133 if (IS_DNODE(node_blk)) {
134 if (S_ISDIR(le16_to_cpu(f2fs_inode->i.i_mode)))
135 type = CURSEG_HOT_NODE;
136 else
137 type = CURSEG_WARM_NODE;
138 }
139
140 if ((get_sb(feature) & cpu_to_le32(F2FS_FEATURE_RO)) &&
141 type != CURSEG_HOT_NODE)
142 type = CURSEG_HOT_NODE;
143
144 get_node_info(sbi, dn->nid, &ni);
145 set_summary(&sum, dn->nid, 0, ni.version);
146 ret = reserve_new_block(sbi, &blkaddr, &sum, type, !ofs);
147 if (ret) {
148 free(node_blk);
149 return 0;
150 }
151
152 /* update nat info */
153 update_nat_blkaddr(sbi, le32_to_cpu(f2fs_inode->footer.ino),
154 dn->nid, blkaddr);
155
156 dn->node_blk = node_blk;
157 inc_inode_blocks(dn);
158 return blkaddr;
159 }
160
161 /*
162 * get_node_path - Get the index path of pgoff_t block
163 * @offset: offset in the current index node block.
164 * @noffset: NO. of the index block within a file.
165 * return: depth of the index path.
166 *
167 * By default, it sets inline_xattr and inline_data
168 */
get_node_path(struct f2fs_node * node,long block,int offset[4],unsigned int noffset[4])169 static int get_node_path(struct f2fs_node *node, long block,
170 int offset[4], unsigned int noffset[4])
171 {
172 const long direct_index = ADDRS_PER_INODE(&node->i);
173 const long direct_blks = ADDRS_PER_BLOCK(&node->i);
174 const long dptrs_per_blk = NIDS_PER_BLOCK;
175 const long indirect_blks = ADDRS_PER_BLOCK(&node->i) * NIDS_PER_BLOCK;
176 const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK;
177 int n = 0;
178 int level = 0;
179
180 noffset[0] = 0;
181 if (block < direct_index) {
182 offset[n] = block;
183 goto got;
184 }
185
186 block -= direct_index;
187 if (block < direct_blks) {
188 offset[n++] = NODE_DIR1_BLOCK;
189 noffset[n]= 1;
190 offset[n] = block;
191 level = 1;
192 goto got;
193 }
194 block -= direct_blks;
195 if (block < direct_blks) {
196 offset[n++] = NODE_DIR2_BLOCK;
197 noffset[n] = 2;
198 offset[n] = block;
199 level = 1;
200 goto got;
201 }
202 block -= direct_blks;
203 if (block < indirect_blks) {
204 offset[n++] = NODE_IND1_BLOCK;
205 noffset[n] = 3;
206 offset[n++] = block / direct_blks;
207 noffset[n] = 4 + offset[n - 1];
208 offset[n] = block % direct_blks;
209 level = 2;
210 goto got;
211 }
212 block -= indirect_blks;
213 if (block < indirect_blks) {
214 offset[n++] = NODE_IND2_BLOCK;
215 noffset[n] = 4 + dptrs_per_blk;
216 offset[n++] = block / direct_blks;
217 noffset[n] = 5 + dptrs_per_blk + offset[n - 1];
218 offset[n] = block % direct_blks;
219 level = 2;
220 goto got;
221 }
222 block -= indirect_blks;
223 if (block < dindirect_blks) {
224 offset[n++] = NODE_DIND_BLOCK;
225 noffset[n] = 5 + (dptrs_per_blk * 2);
226 offset[n++] = block / indirect_blks;
227 noffset[n] = 6 + (dptrs_per_blk * 2) +
228 offset[n - 1] * (dptrs_per_blk + 1);
229 offset[n++] = (block / direct_blks) % dptrs_per_blk;
230 noffset[n] = 7 + (dptrs_per_blk * 2) +
231 offset[n - 2] * (dptrs_per_blk + 1) +
232 offset[n - 1];
233 offset[n] = block % direct_blks;
234 level = 3;
235 goto got;
236 } else {
237 ASSERT(0);
238 }
239 got:
240 return level;
241 }
242
get_dnode_of_data(struct f2fs_sb_info * sbi,struct dnode_of_data * dn,pgoff_t index,int mode)243 int get_dnode_of_data(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
244 pgoff_t index, int mode)
245 {
246 int offset[4];
247 unsigned int noffset[4];
248 struct f2fs_node *parent = NULL;
249 nid_t nids[4];
250 block_t nblk[4];
251 struct node_info ni;
252 int level, i;
253 int ret;
254
255 level = get_node_path(dn->inode_blk, index, offset, noffset);
256
257 nids[0] = dn->nid;
258 parent = dn->inode_blk;
259 if (level != 0)
260 nids[1] = get_nid(parent, offset[0], 1);
261 else
262 dn->node_blk = dn->inode_blk;
263
264 get_node_info(sbi, nids[0], &ni);
265 nblk[0] = ni.blk_addr;
266
267 for (i = 1; i <= level; i++) {
268 if (!nids[i] && mode == ALLOC_NODE) {
269 f2fs_alloc_nid(sbi, &nids[i]);
270
271 dn->nid = nids[i];
272
273 /* Function new_node_blk get a new f2fs_node blk and update*/
274 /* We should make sure that dn->node_blk == NULL*/
275 nblk[i] = new_node_block(sbi, dn, noffset[i]);
276 if (!nblk[i]) {
277 f2fs_release_nid(sbi, nids[i]);
278 c.alloc_failed = 1;
279 return -EINVAL;
280 }
281
282 set_nid(parent, offset[i - 1], nids[i], i == 1);
283 } else {
284 /* If Sparse file no read API, */
285 struct node_info ni;
286
287 get_node_info(sbi, nids[i], &ni);
288 dn->node_blk = calloc(BLOCK_SZ, 1);
289 ASSERT(dn->node_blk);
290
291 ret = dev_read_block(dn->node_blk, ni.blk_addr);
292 ASSERT(ret >= 0);
293
294 nblk[i] = ni.blk_addr;
295 }
296
297 if (mode == ALLOC_NODE){
298 /* Parent node may have changed */
299 ret = dev_write_block(parent, nblk[i - 1]);
300 ASSERT(ret >= 0);
301 }
302 if (i != 1)
303 free(parent);
304
305 if (i < level) {
306 parent = dn->node_blk;
307 nids[i + 1] = get_nid(parent, offset[i], 0);
308 }
309 }
310
311 dn->nid = nids[level];
312 dn->ofs_in_node = offset[level];
313 dn->data_blkaddr = datablock_addr(dn->node_blk, dn->ofs_in_node);
314 dn->node_blkaddr = nblk[level];
315 return 0;
316 }
317