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