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