1 /**
2 * dir.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
room_for_filename(const u8 * bitmap,int slots,int max_slots)19 static int room_for_filename(const u8 *bitmap, int slots, int max_slots)
20 {
21 int bit_start = 0;
22 int zero_start, zero_end;
23 next:
24 zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start);
25 if (zero_start >= max_slots)
26 return max_slots;
27
28 zero_end = find_next_bit_le(bitmap, max_slots, zero_start + 1);
29
30 if (zero_end - zero_start >= slots)
31 return zero_start;
32 bit_start = zero_end;
33 goto next;
34
35 }
36
make_dentry_ptr(struct f2fs_dentry_ptr * d,struct f2fs_node * node_blk,void * src,int type)37 void make_dentry_ptr(struct f2fs_dentry_ptr *d, struct f2fs_node *node_blk,
38 void *src, int type)
39 {
40 if (type == 1) {
41 struct f2fs_dentry_block *t = (struct f2fs_dentry_block *)src;
42 d->max = NR_DENTRY_IN_BLOCK;
43 d->nr_bitmap = SIZE_OF_DENTRY_BITMAP;
44 d->bitmap = t->dentry_bitmap;
45 d->dentry = t->dentry;
46 d->filename = t->filename;
47 } else {
48 int entry_cnt = NR_INLINE_DENTRY(node_blk);
49 int bitmap_size = INLINE_DENTRY_BITMAP_SIZE(node_blk);
50 int reserved_size = INLINE_RESERVED_SIZE(node_blk);
51
52 d->max = entry_cnt;
53 d->nr_bitmap = bitmap_size;
54 d->bitmap = (u8 *)src;
55 d->dentry = (struct f2fs_dir_entry *)
56 ((char *)src + bitmap_size + reserved_size);
57 d->filename = (__u8 (*)[F2FS_SLOT_LEN])((char *)src +
58 bitmap_size + reserved_size +
59 SIZE_OF_DIR_ENTRY * entry_cnt);
60 }
61 }
62
find_target_dentry(const u8 * name,unsigned int len,f2fs_hash_t namehash,int * max_slots,struct f2fs_dentry_ptr * d)63 static struct f2fs_dir_entry *find_target_dentry(const u8 *name,
64 unsigned int len, f2fs_hash_t namehash, int *max_slots,
65 struct f2fs_dentry_ptr *d)
66 {
67 struct f2fs_dir_entry *de;
68 unsigned long bit_pos = 0;
69 int max_len = 0;
70
71 if (max_slots)
72 *max_slots = 0;
73 while (bit_pos < (unsigned long)d->max) {
74 if (!test_bit_le(bit_pos, d->bitmap)) {
75 bit_pos++;
76 max_len++;
77 continue;
78 }
79
80 de = &d->dentry[bit_pos];
81 if (le16_to_cpu(de->name_len) == len &&
82 de->hash_code == namehash &&
83 !memcmp(d->filename[bit_pos], name, len)) {
84 goto found;
85 }
86
87 if (max_slots && max_len > *max_slots)
88 *max_slots = max_len;
89 max_len = 0;
90 bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
91 }
92 de = NULL;
93 found:
94 if (max_slots && max_len > *max_slots)
95 *max_slots = max_len;
96 return de;
97 }
98
find_in_block(void * block,const u8 * name,int len,f2fs_hash_t namehash,int * max_slots)99 static struct f2fs_dir_entry *find_in_block(void *block,
100 const u8 *name, int len, f2fs_hash_t namehash,
101 int *max_slots)
102 {
103 struct f2fs_dentry_ptr d;
104
105 make_dentry_ptr(&d, NULL, block, 1);
106 return find_target_dentry(name, len, namehash, max_slots, &d);
107 }
108
find_in_level(struct f2fs_sb_info * sbi,struct f2fs_node * dir,unsigned int level,struct dentry * de)109 static int find_in_level(struct f2fs_sb_info *sbi,struct f2fs_node *dir,
110 unsigned int level, struct dentry *de)
111 {
112 unsigned int nbucket, nblock;
113 unsigned int bidx, end_block;
114 struct f2fs_dir_entry *dentry = NULL;
115 struct dnode_of_data dn;
116 void *dentry_blk;
117 int max_slots = 214;
118 nid_t ino = le32_to_cpu(dir->footer.ino);
119 f2fs_hash_t namehash;
120 unsigned int dir_level = dir->i.i_dir_level;
121 int ret = 0;
122
123 namehash = f2fs_dentry_hash(de->name, de->len);
124
125 nbucket = dir_buckets(level, dir_level);
126 nblock = bucket_blocks(level);
127
128 bidx = dir_block_index(level, dir_level, le32_to_cpu(namehash) % nbucket);
129 end_block = bidx + nblock;
130
131 dentry_blk = calloc(BLOCK_SZ, 1);
132 ASSERT(dentry_blk);
133
134 memset(&dn, 0, sizeof(dn));
135 for (; bidx < end_block; bidx++) {
136
137 /* Firstly, we should know direct node of target data blk */
138 if (dn.node_blk && dn.node_blk != dn.inode_blk)
139 free(dn.node_blk);
140
141 set_new_dnode(&dn, dir, NULL, ino);
142 get_dnode_of_data(sbi, &dn, bidx, LOOKUP_NODE);
143 if (dn.data_blkaddr == NULL_ADDR)
144 continue;
145
146 ret = dev_read_block(dentry_blk, dn.data_blkaddr);
147 ASSERT(ret >= 0);
148
149 dentry = find_in_block(dentry_blk, de->name, de->len,
150 namehash, &max_slots);
151 if (dentry) {
152 ret = 1;
153 de->ino = le32_to_cpu(dentry->ino);
154 break;
155 }
156 }
157
158 if (dn.node_blk && dn.node_blk != dn.inode_blk)
159 free(dn.node_blk);
160 free(dentry_blk);
161
162 return ret;
163 }
164
f2fs_find_entry(struct f2fs_sb_info * sbi,struct f2fs_node * dir,struct dentry * de)165 static int f2fs_find_entry(struct f2fs_sb_info *sbi,
166 struct f2fs_node *dir, struct dentry *de)
167 {
168 unsigned int max_depth;
169 unsigned int level;
170
171 max_depth = le32_to_cpu(dir->i.i_current_depth);
172 for (level = 0; level < max_depth; level ++) {
173 if (find_in_level(sbi, dir, level, de))
174 return 1;
175 }
176 return 0;
177 }
178
179 /* return ino if file exists, otherwise return 0 */
f2fs_lookup(struct f2fs_sb_info * sbi,struct f2fs_node * dir,u8 * name,int len)180 nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
181 u8 *name, int len)
182 {
183 int err;
184 struct dentry de = {
185 .name = name,
186 .len = len,
187 };
188
189 err = f2fs_find_entry(sbi, dir, &de);
190 if (err == 1)
191 return de.ino;
192 else
193 return 0;
194 }
195
f2fs_update_dentry(nid_t ino,int file_type,struct f2fs_dentry_ptr * d,const unsigned char * name,int len,f2fs_hash_t name_hash,unsigned int bit_pos)196 static void f2fs_update_dentry(nid_t ino, int file_type,
197 struct f2fs_dentry_ptr *d,
198 const unsigned char *name, int len, f2fs_hash_t name_hash,
199 unsigned int bit_pos)
200 {
201 struct f2fs_dir_entry *de;
202 int slots = GET_DENTRY_SLOTS(len);
203 int i;
204
205 de = &d->dentry[bit_pos];
206 de->name_len = cpu_to_le16(len);
207 de->hash_code = name_hash;
208 memcpy(d->filename[bit_pos], name, len);
209 d->filename[bit_pos][len] = 0;
210 de->ino = cpu_to_le32(ino);
211 de->file_type = file_type;
212 for (i = 0; i < slots; i++)
213 test_and_set_bit_le(bit_pos + i, d->bitmap);
214 }
215
216 /*
217 * f2fs_add_link - Add a new file(dir) to parent dir.
218 */
f2fs_add_link(struct f2fs_sb_info * sbi,struct f2fs_node * parent,const unsigned char * name,int name_len,nid_t ino,int file_type,block_t p_blkaddr,int inc_link)219 int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
220 const unsigned char *name, int name_len, nid_t ino,
221 int file_type, block_t p_blkaddr, int inc_link)
222 {
223 int level = 0, current_depth, bit_pos;
224 int nbucket, nblock, bidx, block;
225 int slots = GET_DENTRY_SLOTS(name_len);
226 f2fs_hash_t dentry_hash = f2fs_dentry_hash(name, name_len);
227 struct f2fs_dentry_block *dentry_blk;
228 struct f2fs_dentry_ptr d;
229 struct dnode_of_data dn;
230 nid_t pino = le32_to_cpu(parent->footer.ino);
231 unsigned int dir_level = parent->i.i_dir_level;
232 int ret;
233
234 if (parent == NULL)
235 return -EINVAL;
236
237 if (!pino) {
238 ERR_MSG("Wrong parent ino:%d \n", pino);
239 return -EINVAL;
240 }
241
242 dentry_blk = calloc(BLOCK_SZ, 1);
243 ASSERT(dentry_blk);
244
245 current_depth = le32_to_cpu(parent->i.i_current_depth);
246 start:
247 if (current_depth == MAX_DIR_HASH_DEPTH) {
248 free(dentry_blk);
249 ERR_MSG("\tError: MAX_DIR_HASH\n");
250 return -ENOSPC;
251 }
252
253 /* Need a new dentry block */
254 if (level == current_depth)
255 ++current_depth;
256
257 nbucket = dir_buckets(level, dir_level);
258 nblock = bucket_blocks(level);
259 bidx = dir_block_index(level, dir_level, le32_to_cpu(dentry_hash) % nbucket);
260
261 memset(&dn, 0, sizeof(dn));
262 for (block = bidx; block <= (bidx + nblock - 1); block++) {
263
264 /* Firstly, we should know the direct node of target data blk */
265 if (dn.node_blk && dn.node_blk != dn.inode_blk)
266 free(dn.node_blk);
267
268 set_new_dnode(&dn, parent, NULL, pino);
269 get_dnode_of_data(sbi, &dn, block, ALLOC_NODE);
270
271 if (dn.data_blkaddr == NULL_ADDR) {
272 new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
273 } else {
274 ret = dev_read_block(dentry_blk, dn.data_blkaddr);
275 ASSERT(ret >= 0);
276 }
277 bit_pos = room_for_filename(dentry_blk->dentry_bitmap,
278 slots, NR_DENTRY_IN_BLOCK);
279
280 if (bit_pos < NR_DENTRY_IN_BLOCK)
281 goto add_dentry;
282 }
283 level ++;
284 goto start;
285
286 add_dentry:
287 make_dentry_ptr(&d, NULL, (void *)dentry_blk, 1);
288 f2fs_update_dentry(ino, file_type, &d, name, name_len, dentry_hash, bit_pos);
289
290 ret = dev_write_block(dentry_blk, dn.data_blkaddr);
291 ASSERT(ret >= 0);
292
293 /*
294 * Parent inode needs updating, because its inode info may be changed.
295 * such as i_current_depth and i_blocks.
296 */
297 if (parent->i.i_current_depth != cpu_to_le32(current_depth)) {
298 parent->i.i_current_depth = cpu_to_le32(current_depth);
299 dn.idirty = 1;
300 }
301
302 /* Update parent's i_links info*/
303 if (inc_link && (file_type == F2FS_FT_DIR)){
304 u32 links = le32_to_cpu(parent->i.i_links);
305 parent->i.i_links = cpu_to_le32(links + 1);
306 dn.idirty = 1;
307 }
308
309 if ((__u64)((block + 1) * F2FS_BLKSIZE) >
310 le64_to_cpu(parent->i.i_size)) {
311 parent->i.i_size = cpu_to_le64((block + 1) * F2FS_BLKSIZE);
312 dn.idirty = 1;
313 }
314
315 if (dn.ndirty) {
316 ret = dev_write_block(dn.node_blk, dn.node_blkaddr);
317 ASSERT(ret >= 0);
318 }
319
320 if (dn.idirty) {
321 ASSERT(parent == dn.inode_blk);
322 ret = dev_write_block(dn.inode_blk, p_blkaddr);
323 ASSERT(ret >= 0);
324 }
325
326 if (dn.node_blk != dn.inode_blk)
327 free(dn.node_blk);
328 free(dentry_blk);
329 return 0;
330 }
331
make_empty_dir(struct f2fs_sb_info * sbi,struct f2fs_node * inode)332 static void make_empty_dir(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
333 {
334 struct f2fs_dentry_block *dent_blk;
335 nid_t ino = le32_to_cpu(inode->footer.ino);
336 nid_t pino = le32_to_cpu(inode->i.i_pino);
337 struct f2fs_summary sum;
338 struct node_info ni;
339 block_t blkaddr = NULL_ADDR;
340 int ret;
341
342 get_node_info(sbi, ino, &ni);
343
344 dent_blk = calloc(BLOCK_SZ, 1);
345 ASSERT(dent_blk);
346
347 dent_blk->dentry[0].hash_code = 0;
348 dent_blk->dentry[0].ino = cpu_to_le32(ino);
349 dent_blk->dentry[0].name_len = cpu_to_le16(1);
350 dent_blk->dentry[0].file_type = F2FS_FT_DIR;
351 memcpy(dent_blk->filename[0], ".", 1);
352
353 dent_blk->dentry[1].hash_code = 0;
354 dent_blk->dentry[1].ino = cpu_to_le32(pino);
355 dent_blk->dentry[1].name_len = cpu_to_le16(2);
356 dent_blk->dentry[1].file_type = F2FS_FT_DIR;
357 memcpy(dent_blk->filename[1], "..", 2);
358
359 test_and_set_bit_le(0, dent_blk->dentry_bitmap);
360 test_and_set_bit_le(1, dent_blk->dentry_bitmap);
361
362 set_summary(&sum, ino, 0, ni.version);
363 reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA);
364
365 ret = dev_write_block(dent_blk, blkaddr);
366 ASSERT(ret >= 0);
367
368 inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
369 free(dent_blk);
370 }
371
page_symlink(struct f2fs_sb_info * sbi,struct f2fs_node * inode,const char * symname,int symlen)372 static void page_symlink(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
373 const char *symname, int symlen)
374 {
375 nid_t ino = le32_to_cpu(inode->footer.ino);
376 struct f2fs_summary sum;
377 struct node_info ni;
378 char *data_blk;
379 block_t blkaddr = NULL_ADDR;
380 int ret;
381
382 get_node_info(sbi, ino, &ni);
383
384 /* store into inline_data */
385 if ((unsigned long)(symlen + 1) <= MAX_INLINE_DATA(inode)) {
386 inode->i.i_inline |= F2FS_INLINE_DATA;
387 inode->i.i_inline |= F2FS_DATA_EXIST;
388 memcpy(inline_data_addr(inode), symname, symlen);
389 return;
390 }
391
392 data_blk = calloc(BLOCK_SZ, 1);
393 ASSERT(data_blk);
394
395 memcpy(data_blk, symname, symlen);
396
397 set_summary(&sum, ino, 0, ni.version);
398 reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA);
399
400 ret = dev_write_block(data_blk, blkaddr);
401 ASSERT(ret >= 0);
402
403 inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
404 free(data_blk);
405 }
406
init_inode_block(struct f2fs_sb_info * sbi,struct f2fs_node * node_blk,struct dentry * de)407 static void init_inode_block(struct f2fs_sb_info *sbi,
408 struct f2fs_node *node_blk, struct dentry *de)
409 {
410 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
411 mode_t mode = de->mode;
412 int links = 1;
413 unsigned int size;
414 int blocks = 1;
415
416 if (de->file_type == F2FS_FT_DIR) {
417 mode |= S_IFDIR;
418 size = 4096;
419 links++;
420 blocks++;
421 } else if (de->file_type == F2FS_FT_REG_FILE) {
422 mode |= S_IFREG;
423 size = 0;
424 } else if (de->file_type == F2FS_FT_SYMLINK) {
425 ASSERT(de->link);
426 mode |= S_IFLNK;
427 size = strlen(de->link);
428 if (size + 1 > MAX_INLINE_DATA(node_blk))
429 blocks++;
430 } else {
431 ASSERT(0);
432 }
433
434 node_blk->i.i_mode = cpu_to_le16(mode);
435 node_blk->i.i_advise = 0;
436 node_blk->i.i_uid = cpu_to_le32(de->uid);
437 node_blk->i.i_gid = cpu_to_le32(de->gid);
438 node_blk->i.i_links = cpu_to_le32(links);
439 node_blk->i.i_size = cpu_to_le32(size);
440 node_blk->i.i_blocks = cpu_to_le32(blocks);
441 node_blk->i.i_atime = cpu_to_le64(de->mtime);
442 node_blk->i.i_ctime = cpu_to_le64(de->mtime);
443 node_blk->i.i_mtime = cpu_to_le64(de->mtime);
444 node_blk->i.i_atime_nsec = 0;
445 node_blk->i.i_ctime_nsec = 0;
446 node_blk->i.i_mtime_nsec = 0;
447 node_blk->i.i_generation = 0;
448 if (de->file_type == F2FS_FT_DIR)
449 node_blk->i.i_current_depth = cpu_to_le32(1);
450 else
451 node_blk->i.i_current_depth = cpu_to_le32(0);
452 node_blk->i.i_xattr_nid = 0;
453 node_blk->i.i_flags = 0;
454 node_blk->i.i_inline = F2FS_INLINE_XATTR;
455 node_blk->i.i_pino = cpu_to_le32(de->pino);
456 node_blk->i.i_namelen = cpu_to_le32(de->len);
457 memcpy(node_blk->i.i_name, de->name, de->len);
458 node_blk->i.i_name[de->len] = 0;
459
460 if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
461 node_blk->i.i_inline |= F2FS_EXTRA_ATTR;
462 node_blk->i.i_extra_isize =
463 cpu_to_le16(F2FS_TOTAL_EXTRA_ATTR_SIZE);
464 }
465
466 node_blk->footer.ino = cpu_to_le32(de->ino);
467 node_blk->footer.nid = cpu_to_le32(de->ino);
468 node_blk->footer.flag = 0;
469 node_blk->footer.cp_ver = ckpt->checkpoint_ver;
470
471 if (S_ISDIR(mode))
472 make_empty_dir(sbi, node_blk);
473 else if (S_ISLNK(mode))
474 page_symlink(sbi, node_blk, de->link, size);
475
476 if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
477 node_blk->i.i_inode_checksum =
478 cpu_to_le32(f2fs_inode_chksum(node_blk));
479 }
480
convert_inline_dentry(struct f2fs_sb_info * sbi,struct f2fs_node * node,block_t p_blkaddr)481 int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
482 block_t p_blkaddr)
483 {
484 struct f2fs_inode *inode = &(node->i);
485 unsigned int dir_level = node->i.i_dir_level;
486 nid_t ino = le32_to_cpu(node->footer.ino);
487 char inline_data[MAX_INLINE_DATA(node)];
488 struct dnode_of_data dn;
489 struct f2fs_dentry_ptr d;
490 unsigned long bit_pos = 0;
491 int ret = 0;
492
493 if (!(inode->i_inline & F2FS_INLINE_DENTRY))
494 return 0;
495
496 memcpy(inline_data, inline_data_addr(node), MAX_INLINE_DATA(node));
497 memset(inline_data_addr(node), 0, MAX_INLINE_DATA(node));
498 inode->i_inline &= ~F2FS_INLINE_DENTRY;
499
500 ret = dev_write_block(node, p_blkaddr);
501 ASSERT(ret >= 0);
502
503 memset(&dn, 0, sizeof(dn));
504 if (!dir_level) {
505 struct f2fs_dentry_block *dentry_blk;
506 struct f2fs_dentry_ptr src, dst;
507
508 dentry_blk = calloc(BLOCK_SZ, 1);
509 ASSERT(dentry_blk);
510
511 set_new_dnode(&dn, node, NULL, ino);
512 get_dnode_of_data(sbi, &dn, 0, ALLOC_NODE);
513 if (dn.data_blkaddr == NULL_ADDR)
514 new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
515
516 make_dentry_ptr(&src, node, (void *)inline_data, 2);
517 make_dentry_ptr(&dst, NULL, (void *)dentry_blk, 1);
518
519 /* copy data from inline dentry block to new dentry block */
520 memcpy(dst.bitmap, src.bitmap, src.nr_bitmap);
521 memset(dst.bitmap + src.nr_bitmap, 0,
522 dst.nr_bitmap - src.nr_bitmap);
523
524 memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
525 memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);
526
527 ret = dev_write_block(dentry_blk, dn.data_blkaddr);
528 ASSERT(ret >= 0);
529
530 MSG(1, "%s: copy inline entry to block\n", __func__);
531
532 free(dentry_blk);
533 return ret;
534 }
535
536 make_empty_dir(sbi, node);
537 make_dentry_ptr(&d, node, (void *)inline_data, 2);
538
539 while (bit_pos < (unsigned long)d.max) {
540 struct f2fs_dir_entry *de;
541 const unsigned char *filename;
542 int namelen;
543
544 if (!test_bit_le(bit_pos, d.bitmap)) {
545 bit_pos++;
546 continue;
547 }
548
549 de = &d.dentry[bit_pos];
550 if (!de->name_len) {
551 bit_pos++;
552 continue;
553 }
554
555 filename = d.filename[bit_pos];
556 namelen = le32_to_cpu(de->name_len);
557
558 if (is_dot_dotdot(filename, namelen)) {
559 bit_pos += GET_DENTRY_SLOTS(namelen);
560 continue;
561 }
562
563 ret = f2fs_add_link(sbi, node, filename, namelen,
564 le32_to_cpu(de->ino),
565 de->file_type, p_blkaddr, 0);
566 if (ret)
567 MSG(0, "Convert file \"%s\" ERR=%d\n", filename, ret);
568 else
569 MSG(1, "%s: add inline entry to block\n", __func__);
570
571 bit_pos += GET_DENTRY_SLOTS(namelen);
572 }
573
574 return 0;
575 }
576
f2fs_create(struct f2fs_sb_info * sbi,struct dentry * de)577 int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
578 {
579 struct f2fs_node *parent, *child;
580 struct node_info ni;
581 struct f2fs_summary sum;
582 block_t blkaddr = NULL_ADDR;
583 int ret;
584
585 /* Find if there is a */
586 get_node_info(sbi, de->pino, &ni);
587 if (ni.blk_addr == NULL_ADDR) {
588 MSG(0, "No parent directory pino=%x\n", de->pino);
589 return -1;
590 }
591
592 parent = calloc(BLOCK_SZ, 1);
593 ASSERT(parent);
594
595 ret = dev_read_block(parent, ni.blk_addr);
596 ASSERT(ret >= 0);
597
598 /* Must convert inline dentry before the following opertions */
599 ret = convert_inline_dentry(sbi, parent, ni.blk_addr);
600 if (ret) {
601 MSG(0, "Convert inline dentry for pino=%x failed.\n", de->pino);
602 return -1;
603 }
604
605 ret = f2fs_find_entry(sbi, parent, de);
606 if (ret) {
607 MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
608 de->name, de->pino, ret);
609 if (de->file_type == F2FS_FT_REG_FILE)
610 de->ino = 0;
611 goto free_parent_dir;
612 }
613
614 child = calloc(BLOCK_SZ, 1);
615 ASSERT(child);
616
617 f2fs_alloc_nid(sbi, &de->ino, 1);
618
619 init_inode_block(sbi, child, de);
620
621 ret = f2fs_add_link(sbi, parent, child->i.i_name,
622 le32_to_cpu(child->i.i_namelen),
623 le32_to_cpu(child->footer.ino),
624 map_de_type(le16_to_cpu(child->i.i_mode)),
625 ni.blk_addr, 1);
626 if (ret) {
627 MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
628 de->name, de->pino, ret);
629 goto free_child_dir;
630 }
631
632 /* write child */
633 set_summary(&sum, de->ino, 0, ni.version);
634 reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE);
635
636 /* update nat info */
637 update_nat_blkaddr(sbi, de->ino, de->ino, blkaddr);
638
639 ret = dev_write_block(child, blkaddr);
640 ASSERT(ret >= 0);
641
642 update_free_segments(sbi);
643 MSG(1, "Info: Create %s -> %s\n"
644 " -- ino=%x, type=%x, mode=%x, uid=%x, "
645 "gid=%x, cap=%"PRIx64", size=%lu, pino=%x\n",
646 de->full_path, de->path,
647 de->ino, de->file_type, de->mode,
648 de->uid, de->gid, de->capabilities, de->size, de->pino);
649 free_child_dir:
650 free(child);
651 free_parent_dir:
652 free(parent);
653 return 0;
654 }
655
f2fs_mkdir(struct f2fs_sb_info * sbi,struct dentry * de)656 int f2fs_mkdir(struct f2fs_sb_info *sbi, struct dentry *de)
657 {
658 return f2fs_create(sbi, de);
659 }
660
f2fs_symlink(struct f2fs_sb_info * sbi,struct dentry * de)661 int f2fs_symlink(struct f2fs_sb_info *sbi, struct dentry *de)
662 {
663 return f2fs_create(sbi, de);
664 }
665
f2fs_find_path(struct f2fs_sb_info * sbi,char * path,nid_t * ino)666 int f2fs_find_path(struct f2fs_sb_info *sbi, char *path, nid_t *ino)
667 {
668 struct f2fs_node *parent;
669 struct node_info ni;
670 struct dentry de;
671 int err = 0;
672 int ret;
673 char *p;
674
675 if (path[0] != '/')
676 return -ENOENT;
677
678 *ino = F2FS_ROOT_INO(sbi);
679 parent = calloc(BLOCK_SZ, 1);
680 ASSERT(parent);
681
682 p = strtok(path, "/");
683 while (p) {
684 de.name = (const u8 *)p;
685 de.len = strlen(p);
686
687 get_node_info(sbi, *ino, &ni);
688 if (ni.blk_addr == NULL_ADDR) {
689 err = -ENOENT;
690 goto err;
691 }
692 ret = dev_read_block(parent, ni.blk_addr);
693 ASSERT(ret >= 0);
694
695 ret = f2fs_find_entry(sbi, parent, &de);
696 if (!ret) {
697 err = -ENOENT;
698 goto err;
699 }
700
701 *ino = de.ino;
702 p = strtok(NULL, "/");
703 }
704 err:
705 free(parent);
706 return err;
707 }
708