4 * Many parts of codes are copied from Linux kernel/fs/f2fs.
6 * Copyright (C) 2015 Huawei Ltd.
8 * Hou Pengyang <houpengyang@huawei.com>
9 * Liu Shuoran <liushuoran@huawei.com>
10 * Jaegeuk Kim <jaegeuk@kernel.org>
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.
20 static int room_for_filename(const u8 *bitmap, int slots, int max_slots)
23 int zero_start, zero_end;
25 zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start);
26 if (zero_start >= max_slots)
29 zero_end = find_next_bit_le(bitmap, max_slots, zero_start + 1);
31 if (zero_end - zero_start >= slots)
38 void make_dentry_ptr(struct f2fs_dentry_ptr *d, struct f2fs_node *node_blk,
42 struct f2fs_dentry_block *t = (struct f2fs_dentry_block *)src;
43 d->max = NR_DENTRY_IN_BLOCK;
44 d->nr_bitmap = SIZE_OF_DENTRY_BITMAP;
45 d->bitmap = t->dentry_bitmap;
46 d->dentry = t->dentry;
47 d->filename = t->filename;
49 int entry_cnt = NR_INLINE_DENTRY(node_blk);
50 int bitmap_size = INLINE_DENTRY_BITMAP_SIZE(node_blk);
51 int reserved_size = INLINE_RESERVED_SIZE(node_blk);
54 d->nr_bitmap = bitmap_size;
55 d->bitmap = (u8 *)src;
56 d->dentry = (struct f2fs_dir_entry *)
57 ((char *)src + bitmap_size + reserved_size);
58 d->filename = (__u8 (*)[F2FS_SLOT_LEN])((char *)src +
59 bitmap_size + reserved_size +
60 SIZE_OF_DIR_ENTRY * entry_cnt);
64 static struct f2fs_dir_entry *find_target_dentry(const u8 *name,
65 unsigned int len, f2fs_hash_t namehash, int *max_slots,
66 struct f2fs_dentry_ptr *d)
68 struct f2fs_dir_entry *de;
69 unsigned long bit_pos = 0;
74 while (bit_pos < (unsigned long)d->max) {
75 if (!test_bit_le(bit_pos, d->bitmap)) {
81 de = &d->dentry[bit_pos];
82 if (le16_to_cpu(de->name_len) == len &&
83 de->hash_code == namehash &&
84 !memcmp(d->filename[bit_pos], name, len)) {
88 if (max_slots && max_len > *max_slots)
91 bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
95 if (max_slots && max_len > *max_slots)
100 static struct f2fs_dir_entry *find_in_block(void *block,
101 const u8 *name, int len, f2fs_hash_t namehash,
104 struct f2fs_dentry_ptr d;
106 make_dentry_ptr(&d, NULL, block, 1);
107 return find_target_dentry(name, len, namehash, max_slots, &d);
110 static int find_in_level(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
111 unsigned int level, struct dentry *de)
113 unsigned int nbucket, nblock;
114 unsigned int bidx, end_block;
115 struct f2fs_dir_entry *dentry = NULL;
116 struct dnode_of_data dn;
119 nid_t ino = le32_to_cpu(dir->footer.ino);
120 f2fs_hash_t namehash;
121 unsigned int dir_level = dir->i.i_dir_level;
124 namehash = f2fs_dentry_hash(get_encoding(sbi), IS_CASEFOLDED(&dir->i),
127 nbucket = dir_buckets(level, dir_level);
128 nblock = bucket_blocks(level);
130 bidx = dir_block_index(level, dir_level, le32_to_cpu(namehash) % nbucket);
131 end_block = bidx + nblock;
133 dentry_blk = calloc(BLOCK_SZ, 1);
136 memset(&dn, 0, sizeof(dn));
137 for (; bidx < end_block; bidx++) {
139 /* Firstly, we should know direct node of target data blk */
140 if (dn.node_blk && dn.node_blk != dn.inode_blk)
143 set_new_dnode(&dn, dir, NULL, ino);
144 get_dnode_of_data(sbi, &dn, bidx, LOOKUP_NODE);
145 if (dn.data_blkaddr == NULL_ADDR)
148 ret = dev_read_block(dentry_blk, dn.data_blkaddr);
151 dentry = find_in_block(dentry_blk, de->name, de->len,
152 namehash, &max_slots);
155 de->ino = le32_to_cpu(dentry->ino);
160 if (dn.node_blk && dn.node_blk != dn.inode_blk)
167 static int f2fs_find_entry(struct f2fs_sb_info *sbi,
168 struct f2fs_node *dir, struct dentry *de)
170 unsigned int max_depth;
173 max_depth = le32_to_cpu(dir->i.i_current_depth);
174 for (level = 0; level < max_depth; level ++) {
175 if (find_in_level(sbi, dir, level, de))
181 /* return ino if file exists, otherwise return 0 */
182 nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
191 err = f2fs_find_entry(sbi, dir, &de);
198 static void f2fs_update_dentry(nid_t ino, int file_type,
199 struct f2fs_dentry_ptr *d,
200 const unsigned char *name, int len, f2fs_hash_t name_hash,
201 unsigned int bit_pos)
203 struct f2fs_dir_entry *de;
204 int slots = GET_DENTRY_SLOTS(len);
207 de = &d->dentry[bit_pos];
208 de->name_len = cpu_to_le16(len);
209 de->hash_code = name_hash;
210 memcpy(d->filename[bit_pos], name, len);
211 d->filename[bit_pos][len] = 0;
212 de->ino = cpu_to_le32(ino);
213 de->file_type = file_type;
214 for (i = 0; i < slots; i++)
215 test_and_set_bit_le(bit_pos + i, d->bitmap);
219 * f2fs_add_link - Add a new file(dir) to parent dir.
221 int f2fs_add_link(struct f2fs_sb_info *sbi, struct f2fs_node *parent,
222 const unsigned char *name, int name_len, nid_t ino,
223 int file_type, block_t p_blkaddr, int inc_link)
225 int level = 0, current_depth, bit_pos;
226 int nbucket, nblock, bidx, block;
227 int slots = GET_DENTRY_SLOTS(name_len);
228 f2fs_hash_t dentry_hash = f2fs_dentry_hash(get_encoding(sbi),
229 IS_CASEFOLDED(&parent->i),
231 struct f2fs_dentry_block *dentry_blk;
232 struct f2fs_dentry_ptr d;
233 struct dnode_of_data dn;
234 nid_t pino = le32_to_cpu(parent->footer.ino);
235 unsigned int dir_level = parent->i.i_dir_level;
242 ERR_MSG("Wrong parent ino:%d \n", pino);
246 dentry_blk = calloc(BLOCK_SZ, 1);
249 current_depth = le32_to_cpu(parent->i.i_current_depth);
251 if (current_depth == MAX_DIR_HASH_DEPTH) {
253 ERR_MSG("\tError: MAX_DIR_HASH\n");
257 /* Need a new dentry block */
258 if (level == current_depth)
261 nbucket = dir_buckets(level, dir_level);
262 nblock = bucket_blocks(level);
263 bidx = dir_block_index(level, dir_level, le32_to_cpu(dentry_hash) % nbucket);
265 memset(&dn, 0, sizeof(dn));
266 for (block = bidx; block <= (bidx + nblock - 1); block++) {
268 /* Firstly, we should know the direct node of target data blk */
269 if (dn.node_blk && dn.node_blk != dn.inode_blk)
272 set_new_dnode(&dn, parent, NULL, pino);
273 get_dnode_of_data(sbi, &dn, block, ALLOC_NODE);
275 if (dn.data_blkaddr == NULL_ADDR) {
276 new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
278 ret = dev_read_block(dentry_blk, dn.data_blkaddr);
281 bit_pos = room_for_filename(dentry_blk->dentry_bitmap,
282 slots, NR_DENTRY_IN_BLOCK);
284 if (bit_pos < NR_DENTRY_IN_BLOCK)
291 make_dentry_ptr(&d, NULL, (void *)dentry_blk, 1);
292 f2fs_update_dentry(ino, file_type, &d, name, name_len, dentry_hash, bit_pos);
294 ret = dev_write_block(dentry_blk, dn.data_blkaddr);
298 * Parent inode needs updating, because its inode info may be changed.
299 * such as i_current_depth and i_blocks.
301 if (parent->i.i_current_depth != cpu_to_le32(current_depth)) {
302 parent->i.i_current_depth = cpu_to_le32(current_depth);
306 /* Update parent's i_links info*/
307 if (inc_link && (file_type == F2FS_FT_DIR)){
308 u32 links = le32_to_cpu(parent->i.i_links);
309 parent->i.i_links = cpu_to_le32(links + 1);
313 if ((__u64)((block + 1) * F2FS_BLKSIZE) >
314 le64_to_cpu(parent->i.i_size)) {
315 parent->i.i_size = cpu_to_le64((block + 1) * F2FS_BLKSIZE);
320 ret = dev_write_block(dn.node_blk, dn.node_blkaddr);
325 ASSERT(parent == dn.inode_blk);
326 ret = write_inode(dn.inode_blk, p_blkaddr);
330 if (dn.node_blk != dn.inode_blk)
336 static void make_empty_dir(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
338 struct f2fs_dentry_block *dent_blk;
339 nid_t ino = le32_to_cpu(inode->footer.ino);
340 nid_t pino = le32_to_cpu(inode->i.i_pino);
341 struct f2fs_summary sum;
343 block_t blkaddr = NULL_ADDR;
346 get_node_info(sbi, ino, &ni);
348 dent_blk = calloc(BLOCK_SZ, 1);
351 dent_blk->dentry[0].hash_code = 0;
352 dent_blk->dentry[0].ino = cpu_to_le32(ino);
353 dent_blk->dentry[0].name_len = cpu_to_le16(1);
354 dent_blk->dentry[0].file_type = F2FS_FT_DIR;
355 memcpy(dent_blk->filename[0], ".", 1);
357 dent_blk->dentry[1].hash_code = 0;
358 dent_blk->dentry[1].ino = cpu_to_le32(pino);
359 dent_blk->dentry[1].name_len = cpu_to_le16(2);
360 dent_blk->dentry[1].file_type = F2FS_FT_DIR;
361 memcpy(dent_blk->filename[1], "..", 2);
363 test_and_set_bit_le(0, dent_blk->dentry_bitmap);
364 test_and_set_bit_le(1, dent_blk->dentry_bitmap);
366 set_summary(&sum, ino, 0, ni.version);
367 ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA, 0);
370 ret = dev_write_block(dent_blk, blkaddr);
373 inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
377 static void page_symlink(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
378 const char *symname, int symlen)
380 nid_t ino = le32_to_cpu(inode->footer.ino);
381 struct f2fs_summary sum;
384 block_t blkaddr = NULL_ADDR;
387 get_node_info(sbi, ino, &ni);
389 /* store into inline_data */
390 if ((unsigned long)(symlen + 1) <= MAX_INLINE_DATA(inode)) {
391 inode->i.i_inline |= F2FS_INLINE_DATA;
392 inode->i.i_inline |= F2FS_DATA_EXIST;
393 memcpy(inline_data_addr(inode), symname, symlen);
397 data_blk = calloc(BLOCK_SZ, 1);
400 memcpy(data_blk, symname, symlen);
402 set_summary(&sum, ino, 0, ni.version);
403 ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA, 0);
406 ret = dev_write_block(data_blk, blkaddr);
409 inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
413 static inline int is_extension_exist(const char *s,
416 unsigned int slen = strlen(s);
417 unsigned int sublen = strlen(sub);
421 * filename format of multimedia file should be defined as:
422 * "filename + '.' + extension + (optional: '.' + temp extension)".
424 if (slen < sublen + 2)
427 for (i = 1; i < slen - sublen; i++) {
430 if (!strncasecmp(s + i + 1, sub, sublen))
437 static void set_file_temperature(struct f2fs_sb_info *sbi,
438 struct f2fs_node *node_blk,
439 const unsigned char *name)
441 __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
442 int i, cold_count, hot_count;
444 cold_count = le32_to_cpu(sbi->raw_super->extension_count);
445 hot_count = sbi->raw_super->hot_ext_count;
447 for (i = 0; i < cold_count + hot_count; i++) {
448 if (is_extension_exist((const char *)name,
449 (const char *)extlist[i]))
453 if (i == cold_count + hot_count)
457 node_blk->i.i_advise |= FADVISE_COLD_BIT;
459 node_blk->i.i_advise |= FADVISE_HOT_BIT;
462 static void init_inode_block(struct f2fs_sb_info *sbi,
463 struct f2fs_node *node_blk, struct dentry *de)
465 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
466 mode_t mode = de->mode;
471 if (de->file_type == F2FS_FT_DIR) {
476 } else if (de->file_type == F2FS_FT_REG_FILE) {
483 } else if (de->file_type == F2FS_FT_SYMLINK) {
490 size = strlen(de->link);
491 if (size + 1 > MAX_INLINE_DATA(node_blk))
497 node_blk->i.i_mode = cpu_to_le16(mode);
498 node_blk->i.i_advise = 0;
499 node_blk->i.i_uid = cpu_to_le32(de->uid);
500 node_blk->i.i_gid = cpu_to_le32(de->gid);
501 node_blk->i.i_links = cpu_to_le32(links);
502 node_blk->i.i_size = cpu_to_le32(size);
503 node_blk->i.i_blocks = cpu_to_le32(blocks);
504 node_blk->i.i_atime = cpu_to_le64(de->mtime);
505 node_blk->i.i_ctime = cpu_to_le64(de->mtime);
506 node_blk->i.i_mtime = cpu_to_le64(de->mtime);
507 node_blk->i.i_atime_nsec = 0;
508 node_blk->i.i_ctime_nsec = 0;
509 node_blk->i.i_mtime_nsec = 0;
510 node_blk->i.i_generation = 0;
511 if (de->file_type == F2FS_FT_DIR)
512 node_blk->i.i_current_depth = cpu_to_le32(1);
514 node_blk->i.i_current_depth = cpu_to_le32(0);
515 node_blk->i.i_xattr_nid = 0;
516 node_blk->i.i_flags = 0;
517 node_blk->i.i_inline = F2FS_INLINE_XATTR;
518 node_blk->i.i_pino = cpu_to_le32(de->pino);
519 node_blk->i.i_namelen = cpu_to_le32(de->len);
520 memcpy(node_blk->i.i_name, de->name, de->len);
521 node_blk->i.i_name[de->len] = 0;
523 if (c.feature & cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR)) {
524 node_blk->i.i_inline |= F2FS_EXTRA_ATTR;
525 node_blk->i.i_extra_isize = cpu_to_le16(calc_extra_isize());
528 set_file_temperature(sbi, node_blk, de->name);
530 node_blk->footer.ino = cpu_to_le32(de->ino);
531 node_blk->footer.nid = cpu_to_le32(de->ino);
532 node_blk->footer.flag = 0;
533 node_blk->footer.cp_ver = ckpt->checkpoint_ver;
534 set_cold_node(node_blk, S_ISDIR(mode));
537 make_empty_dir(sbi, node_blk);
538 } else if (S_ISLNK(mode)) {
539 page_symlink(sbi, node_blk, de->link, size);
545 if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
546 node_blk->i.i_inode_checksum =
547 cpu_to_le32(f2fs_inode_chksum(node_blk));
550 int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
553 struct f2fs_inode *inode = &(node->i);
554 unsigned int dir_level = node->i.i_dir_level;
555 nid_t ino = le32_to_cpu(node->footer.ino);
556 char inline_data[MAX_INLINE_DATA(node)];
557 struct dnode_of_data dn;
558 struct f2fs_dentry_ptr d;
559 unsigned long bit_pos = 0;
562 if (!(inode->i_inline & F2FS_INLINE_DENTRY))
565 memcpy(inline_data, inline_data_addr(node), MAX_INLINE_DATA(node));
566 memset(inline_data_addr(node), 0, MAX_INLINE_DATA(node));
567 inode->i_inline &= ~F2FS_INLINE_DENTRY;
569 ret = dev_write_block(node, p_blkaddr);
572 memset(&dn, 0, sizeof(dn));
574 struct f2fs_dentry_block *dentry_blk;
575 struct f2fs_dentry_ptr src, dst;
577 dentry_blk = calloc(BLOCK_SZ, 1);
580 set_new_dnode(&dn, node, NULL, ino);
581 get_dnode_of_data(sbi, &dn, 0, ALLOC_NODE);
582 if (dn.data_blkaddr == NULL_ADDR)
583 new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
585 make_dentry_ptr(&src, node, (void *)inline_data, 2);
586 make_dentry_ptr(&dst, NULL, (void *)dentry_blk, 1);
588 /* copy data from inline dentry block to new dentry block */
589 memcpy(dst.bitmap, src.bitmap, src.nr_bitmap);
590 memset(dst.bitmap + src.nr_bitmap, 0,
591 dst.nr_bitmap - src.nr_bitmap);
593 memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
594 memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);
596 ret = dev_write_block(dentry_blk, dn.data_blkaddr);
599 MSG(1, "%s: copy inline entry to block\n", __func__);
605 make_empty_dir(sbi, node);
606 make_dentry_ptr(&d, node, (void *)inline_data, 2);
608 while (bit_pos < (unsigned long)d.max) {
609 struct f2fs_dir_entry *de;
610 const unsigned char *filename;
613 if (!test_bit_le(bit_pos, d.bitmap)) {
618 de = &d.dentry[bit_pos];
624 filename = d.filename[bit_pos];
625 namelen = le32_to_cpu(de->name_len);
627 if (is_dot_dotdot(filename, namelen)) {
628 bit_pos += GET_DENTRY_SLOTS(namelen);
632 ret = f2fs_add_link(sbi, node, filename, namelen,
633 le32_to_cpu(de->ino),
634 de->file_type, p_blkaddr, 0);
636 MSG(0, "Convert file \"%s\" ERR=%d\n", filename, ret);
638 MSG(1, "%s: add inline entry to block\n", __func__);
640 bit_pos += GET_DENTRY_SLOTS(namelen);
646 static int cmp_from_devino(const void *a, const void *b) {
647 u64 devino_a = ((struct hardlink_cache_entry*) a)->from_devino;
648 u64 devino_b = ((struct hardlink_cache_entry*) b)->from_devino;
650 return (devino_a > devino_b) - (devino_a < devino_b);
653 struct hardlink_cache_entry *f2fs_search_hardlink(struct f2fs_sb_info *sbi,
656 struct hardlink_cache_entry *find_hardlink = NULL;
657 struct hardlink_cache_entry *found_hardlink = NULL;
660 /* This might be a hardlink, try to find it in the cache */
661 find_hardlink = calloc(1, sizeof(struct hardlink_cache_entry));
662 find_hardlink->from_devino = de->from_devino;
664 search_result = tsearch(find_hardlink, &(sbi->hardlink_cache),
666 ASSERT(search_result != 0);
668 found_hardlink = *(struct hardlink_cache_entry**) search_result;
669 ASSERT(find_hardlink->from_devino == found_hardlink->from_devino);
671 /* If it was already in the cache, free the entry we just created */
672 if (found_hardlink != find_hardlink)
675 return found_hardlink;
678 int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
680 struct f2fs_node *parent, *child;
681 struct hardlink_cache_entry *found_hardlink = NULL;
682 struct node_info ni, hardlink_ni;
683 struct f2fs_summary sum;
684 block_t blkaddr = NULL_ADDR;
687 /* Find if there is a */
688 get_node_info(sbi, de->pino, &ni);
689 if (ni.blk_addr == NULL_ADDR) {
690 MSG(0, "No parent directory pino=%x\n", de->pino);
695 found_hardlink = f2fs_search_hardlink(sbi, de);
697 parent = calloc(BLOCK_SZ, 1);
700 ret = dev_read_block(parent, ni.blk_addr);
703 /* Must convert inline dentry before the following opertions */
704 ret = convert_inline_dentry(sbi, parent, ni.blk_addr);
706 MSG(0, "Convert inline dentry for pino=%x failed.\n", de->pino);
710 ret = f2fs_find_entry(sbi, parent, de);
712 MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
713 de->name, de->pino, ret);
714 if (de->file_type == F2FS_FT_REG_FILE)
716 goto free_parent_dir;
719 child = calloc(BLOCK_SZ, 1);
722 if (found_hardlink && found_hardlink->to_ino) {
724 * If we found this devino in the cache, we're creating a
727 get_node_info(sbi, found_hardlink->to_ino, &hardlink_ni);
728 if (hardlink_ni.blk_addr == NULL_ADDR) {
729 MSG(1, "No original inode for hard link to_ino=%x\n",
730 found_hardlink->to_ino);
734 /* Use previously-recorded inode */
735 de->ino = found_hardlink->to_ino;
736 blkaddr = hardlink_ni.blk_addr;
737 MSG(1, "Info: Creating \"%s\" as hard link to inode %d\n",
740 f2fs_alloc_nid(sbi, &de->ino);
743 init_inode_block(sbi, child, de);
745 ret = f2fs_add_link(sbi, parent, child->i.i_name,
746 le32_to_cpu(child->i.i_namelen),
747 le32_to_cpu(child->footer.ino),
748 map_de_type(le16_to_cpu(child->i.i_mode)),
751 MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
752 de->name, de->pino, ret);
756 if (found_hardlink) {
757 if (!found_hardlink->to_ino) {
758 MSG(2, "Adding inode %d from %s to hardlink cache\n",
760 found_hardlink->to_ino = de->ino;
762 /* Replace child with original block */
765 child = calloc(BLOCK_SZ, 1);
768 ret = dev_read_block(child, blkaddr);
771 /* Increment links and skip to writing block */
772 child->i.i_links = cpu_to_le32(
773 le32_to_cpu(child->i.i_links) + 1);
774 MSG(2, "Number of links on inode %d is now %d\n",
775 de->ino, le32_to_cpu(child->i.i_links));
776 goto write_child_dir;
781 set_summary(&sum, de->ino, 0, ni.version);
782 ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
785 /* update nat info */
786 update_nat_blkaddr(sbi, de->ino, de->ino, blkaddr);
789 ret = dev_write_block(child, blkaddr);
792 update_free_segments(sbi);
793 MSG(1, "Info: Create %s -> %s\n"
794 " -- ino=%x, type=%x, mode=%x, uid=%x, "
795 "gid=%x, cap=%"PRIx64", size=%lu, link=%u "
796 "blocks=%"PRIx64" pino=%x\n",
797 de->full_path, de->path,
798 de->ino, de->file_type, de->mode,
799 de->uid, de->gid, de->capabilities, de->size,
800 le32_to_cpu(child->i.i_links),
801 le64_to_cpu(child->i.i_blocks),
810 int f2fs_mkdir(struct f2fs_sb_info *sbi, struct dentry *de)
812 return f2fs_create(sbi, de);
815 int f2fs_symlink(struct f2fs_sb_info *sbi, struct dentry *de)
817 return f2fs_create(sbi, de);
820 int f2fs_find_path(struct f2fs_sb_info *sbi, char *path, nid_t *ino)
822 struct f2fs_node *parent;
832 *ino = F2FS_ROOT_INO(sbi);
833 parent = calloc(BLOCK_SZ, 1);
836 p = strtok(path, "/");
838 de.name = (const u8 *)p;
841 get_node_info(sbi, *ino, &ni);
842 if (ni.blk_addr == NULL_ADDR) {
846 ret = dev_read_block(parent, ni.blk_addr);
849 ret = f2fs_find_entry(sbi, parent, &de);
856 p = strtok(NULL, "/");