xref: /aosp_15_r20/external/f2fs-tools/fsck/dir.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
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 <[email protected]>
9  *   Liu Shuoran <[email protected]>
10  *   Jaegeuk Kim <[email protected]>
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 #include <search.h>
19 
room_for_filename(const u8 * bitmap,int slots,int max_slots)20 static int room_for_filename(const u8 *bitmap, int slots, int max_slots)
21 {
22 	int bit_start = 0;
23 	int zero_start, zero_end;
24 next:
25 	zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start);
26 	if (zero_start >= max_slots)
27 		return max_slots;
28 
29 	zero_end = find_next_bit_le(bitmap, max_slots, zero_start + 1);
30 
31 	if (zero_end - zero_start >= slots)
32 		return zero_start;
33 	bit_start = zero_end;
34 	goto next;
35 
36 }
37 
make_dentry_ptr(struct f2fs_dentry_ptr * d,struct f2fs_node * node_blk,void * src,int type)38 void make_dentry_ptr(struct f2fs_dentry_ptr *d, struct f2fs_node *node_blk,
39 							void *src, int type)
40 {
41 	if (type == 1) {
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 = F2FS_DENTRY_BLOCK_DENTRIES(t);
47 		d->filename = F2FS_DENTRY_BLOCK_FILENAMES(t);
48 	} else {
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);
52 
53 		d->max = entry_cnt;
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);
61 	}
62 }
63 
find_target_dentry(const u8 * name,unsigned int len,f2fs_hash_t namehash,int * max_slots,struct f2fs_dentry_ptr * d)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)
67 {
68 	struct f2fs_dir_entry *de;
69 	unsigned long bit_pos = 0;
70 	int max_len = 0;
71 
72 	if (max_slots)
73 		*max_slots = 0;
74 	while (bit_pos < (unsigned long)d->max) {
75 		if (!test_bit_le(bit_pos, d->bitmap)) {
76 			bit_pos++;
77 			max_len++;
78 			continue;
79 		}
80 
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)) {
85 			goto found;
86 		}
87 
88 		if (max_slots && max_len > *max_slots)
89 			*max_slots = max_len;
90 		max_len = 0;
91 		bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
92 	}
93 	de = NULL;
94 found:
95 	if (max_slots && max_len > *max_slots)
96 		*max_slots = max_len;
97 	return de;
98 }
99 
find_in_block(void * block,const u8 * name,int len,f2fs_hash_t namehash,int * max_slots)100 static struct f2fs_dir_entry *find_in_block(void *block,
101 		const u8 *name, int len, f2fs_hash_t namehash,
102 		int *max_slots)
103 {
104 	struct f2fs_dentry_ptr d;
105 
106 	make_dentry_ptr(&d, NULL, block, 1);
107 	return find_target_dentry(name, len, namehash, max_slots, &d);
108 }
109 
find_in_level(struct f2fs_sb_info * sbi,struct f2fs_node * dir,unsigned int level,struct dentry * de)110 static int find_in_level(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
111 		unsigned int level, struct dentry *de)
112 {
113 	unsigned int nbucket, nblock;
114 	unsigned int bidx, end_block;
115 	struct f2fs_dir_entry *dentry = NULL;
116 	struct dnode_of_data dn;
117 	void *dentry_blk;
118 	int max_slots = 214;
119 	nid_t ino = le32_to_cpu(F2FS_NODE_FOOTER(dir)->ino);
120 	f2fs_hash_t namehash;
121 	unsigned int dir_level = dir->i.i_dir_level;
122 	int ret = 0;
123 
124 	namehash = f2fs_dentry_hash(get_encoding(sbi), IS_CASEFOLDED(&dir->i),
125 					de->name, de->len);
126 
127 	nbucket = dir_buckets(level, dir_level);
128 	nblock = bucket_blocks(level);
129 
130 	bidx = dir_block_index(level, dir_level, le32_to_cpu(namehash) % nbucket);
131 	end_block = bidx + nblock;
132 
133 	dentry_blk = calloc(F2FS_BLKSIZE, 1);
134 	ASSERT(dentry_blk);
135 
136 	memset(&dn, 0, sizeof(dn));
137 	for (; bidx < end_block; bidx++) {
138 
139 		/* Firstly, we should know direct node of target data blk */
140 		if (dn.node_blk && dn.node_blk != dn.inode_blk)
141 			free(dn.node_blk);
142 
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)
146 			continue;
147 
148 		ret = dev_read_block(dentry_blk, dn.data_blkaddr);
149 		ASSERT(ret >= 0);
150 
151 		dentry = find_in_block(dentry_blk, de->name, de->len,
152 						namehash, &max_slots);
153 		if (dentry) {
154 			ret = 1;
155 			de->ino = le32_to_cpu(dentry->ino);
156 			break;
157 		}
158 	}
159 
160 	if (dn.node_blk && dn.node_blk != dn.inode_blk)
161 		free(dn.node_blk);
162 	free(dentry_blk);
163 
164 	return ret;
165 }
166 
f2fs_find_entry(struct f2fs_sb_info * sbi,struct f2fs_node * dir,struct dentry * de)167 static int f2fs_find_entry(struct f2fs_sb_info *sbi,
168 				struct f2fs_node *dir, struct dentry *de)
169 {
170 	unsigned int max_depth;
171 	unsigned int level;
172 
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))
176 			return 1;
177 	}
178 	return 0;
179 }
180 
181 /* return ino if file exists, otherwise return 0 */
f2fs_lookup(struct f2fs_sb_info * sbi,struct f2fs_node * dir,u8 * name,int len)182 nid_t f2fs_lookup(struct f2fs_sb_info *sbi, struct f2fs_node *dir,
183 				u8 *name, int len)
184 {
185 	int err;
186 	struct dentry de = {
187 		.name = name,
188 		.len = len,
189 	};
190 
191 	err = f2fs_find_entry(sbi, dir, &de);
192 	if (err == 1)
193 		return de.ino;
194 	else
195 		return 0;
196 }
197 
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)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)
202 {
203 	struct f2fs_dir_entry *de;
204 	int slots = GET_DENTRY_SLOTS(len);
205 	int i;
206 
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);
216 }
217 
218 /*
219  * f2fs_add_link - Add a new file(dir) to parent dir.
220  */
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)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)
224 {
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;
229 	struct f2fs_dentry_block *dentry_blk;
230 	struct f2fs_dentry_ptr d;
231 	struct dnode_of_data dn;
232 	nid_t pino;
233 	unsigned int dir_level;
234 	int ret;
235 	bool datablk_alloced = false;
236 
237 	if (parent == NULL)
238 		return -EINVAL;
239 
240 	dentry_hash = f2fs_dentry_hash(get_encoding(sbi),
241 						IS_CASEFOLDED(&parent->i),
242 						name, name_len);
243 	pino = le32_to_cpu(F2FS_NODE_FOOTER(parent)->ino);
244 	dir_level = parent->i.i_dir_level;
245 
246 	if (!pino) {
247 		ERR_MSG("Wrong parent ino:%d \n", pino);
248 		return -EINVAL;
249 	}
250 
251 	dentry_blk = calloc(F2FS_BLKSIZE, 1);
252 	ASSERT(dentry_blk);
253 
254 	current_depth = le32_to_cpu(parent->i.i_current_depth);
255 start:
256 	if (current_depth == MAX_DIR_HASH_DEPTH) {
257 		free(dentry_blk);
258 		ERR_MSG("\tError: MAX_DIR_HASH\n");
259 		return -ENOSPC;
260 	}
261 
262 	/* Need a new dentry block */
263 	if (level == current_depth)
264 		++current_depth;
265 
266 	nbucket = dir_buckets(level, dir_level);
267 	nblock = bucket_blocks(level);
268 	bidx = dir_block_index(level, dir_level, le32_to_cpu(dentry_hash) % nbucket);
269 
270 	memset(&dn, 0, sizeof(dn));
271 	for (block = bidx; block <= (bidx + nblock - 1); block++) {
272 
273 		/* Firstly, we should know the direct node of target data blk */
274 		if (dn.node_blk && dn.node_blk != dn.inode_blk)
275 			free(dn.node_blk);
276 
277 		set_new_dnode(&dn, parent, NULL, pino);
278 		get_dnode_of_data(sbi, &dn, block, ALLOC_NODE);
279 
280 		if (dn.data_blkaddr == NULL_ADDR) {
281 			new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
282 			datablk_alloced = true;
283 		} else {
284 			ret = dev_read_block(dentry_blk, dn.data_blkaddr);
285 			ASSERT(ret >= 0);
286 		}
287 		bit_pos = room_for_filename(dentry_blk->dentry_bitmap,
288 				slots, NR_DENTRY_IN_BLOCK);
289 
290 		if (bit_pos < NR_DENTRY_IN_BLOCK)
291 			goto add_dentry;
292 	}
293 	level ++;
294 	goto start;
295 
296 add_dentry:
297 	make_dentry_ptr(&d, NULL, (void *)dentry_blk, 1);
298 	f2fs_update_dentry(ino, file_type, &d, name, name_len, dentry_hash, bit_pos);
299 
300 	if (c.zoned_model == F2FS_ZONED_HM) {
301 		if (datablk_alloced) {
302 			/* dentry uses hot data segment */
303 			ret = dev_write_block(dentry_blk, dn.data_blkaddr,
304 				f2fs_io_type_to_rw_hint(CURSEG_HOT_DATA));
305 		} else {
306 			ret = update_block(sbi, dentry_blk, &dn.data_blkaddr,
307 					dn.node_blk);
308 			if (dn.inode_blk == dn.node_blk)
309 				dn.idirty = 1;
310 			else
311 				dn.ndirty = 1;
312 		}
313 	} else {
314 		/* dentry uses hot data segment */
315 		ret = dev_write_block(dentry_blk, dn.data_blkaddr,
316 				f2fs_io_type_to_rw_hint(CURSEG_HOT_DATA));
317 	}
318 	ASSERT(ret >= 0);
319 
320 	/*
321 	 * Parent inode needs updating, because its inode info may be changed.
322 	 * such as i_current_depth and i_blocks.
323 	 */
324 	if (parent->i.i_current_depth != cpu_to_le32(current_depth)) {
325 		parent->i.i_current_depth = cpu_to_le32(current_depth);
326 		dn.idirty = 1;
327 	}
328 
329 	/* Update parent's i_links info*/
330 	if (inc_link && (file_type == F2FS_FT_DIR)){
331 		u32 links = le32_to_cpu(parent->i.i_links);
332 		parent->i.i_links = cpu_to_le32(links + 1);
333 		dn.idirty = 1;
334 	}
335 
336 	if ((__u64)((block + 1) * F2FS_BLKSIZE) >
337 					le64_to_cpu(parent->i.i_size)) {
338 		parent->i.i_size = cpu_to_le64((block + 1) * F2FS_BLKSIZE);
339 		dn.idirty = 1;
340 	}
341 
342 	if (dn.ndirty) {
343 		struct seg_entry *se;
344 
345 		/* get segment type for rw hint */
346 		se = get_seg_entry(sbi, GET_SEGNO(sbi, dn.node_blkaddr));
347 		ret = dn.alloced ?
348 			dev_write_block(dn.node_blk, dn.node_blkaddr,
349 					f2fs_io_type_to_rw_hint(se->type)) :
350 			update_block(sbi, dn.node_blk, &dn.node_blkaddr, NULL);
351 		ASSERT(ret >= 0);
352 	}
353 
354 	if (dn.idirty) {
355 		ASSERT(parent == dn.inode_blk);
356 		ret = update_inode(sbi, dn.inode_blk, p_blkaddr);
357 		ASSERT(ret >= 0);
358 	}
359 
360 	if (dn.node_blk != dn.inode_blk)
361 		free(dn.node_blk);
362 	free(dentry_blk);
363 	return 0;
364 }
365 
make_empty_dir(struct f2fs_sb_info * sbi,struct f2fs_node * inode)366 static void make_empty_dir(struct f2fs_sb_info *sbi, struct f2fs_node *inode)
367 {
368 	struct f2fs_dentry_block *dent_blk;
369 	nid_t ino = le32_to_cpu(F2FS_NODE_FOOTER(inode)->ino);
370 	nid_t pino = le32_to_cpu(inode->i.i_pino);
371 	struct f2fs_summary sum;
372 	struct node_info ni;
373 	block_t blkaddr = NULL_ADDR;
374 	int ret;
375 
376 	get_node_info(sbi, ino, &ni);
377 
378 	dent_blk = calloc(F2FS_BLKSIZE, 1);
379 	ASSERT(dent_blk);
380 
381 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 0).hash_code = 0;
382 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 0).ino = cpu_to_le32(ino);
383 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 0).name_len = cpu_to_le16(1);
384 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 0).file_type = F2FS_FT_DIR;
385 	memcpy(F2FS_DENTRY_BLOCK_FILENAME(dent_blk, 0), ".", 1);
386 
387 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 1).hash_code = 0;
388 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 1).ino = cpu_to_le32(pino);
389 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 1).name_len = cpu_to_le16(2);
390 	F2FS_DENTRY_BLOCK_DENTRY(dent_blk, 1).file_type = F2FS_FT_DIR;
391 	memcpy(F2FS_DENTRY_BLOCK_FILENAME(dent_blk, 1), "..", 2);
392 
393 	test_and_set_bit_le(0, dent_blk->dentry_bitmap);
394 	test_and_set_bit_le(1, dent_blk->dentry_bitmap);
395 
396 	set_summary(&sum, ino, 0, ni.version);
397 	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_DATA, 0);
398 	ASSERT(!ret);
399 
400 	ret = dev_write_block(dent_blk, blkaddr,
401 			      f2fs_io_type_to_rw_hint(CURSEG_HOT_DATA));
402 	ASSERT(ret >= 0);
403 
404 	inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
405 	free(dent_blk);
406 }
407 
page_symlink(struct f2fs_sb_info * sbi,struct f2fs_node * inode,const char * symname,int symlen)408 static void page_symlink(struct f2fs_sb_info *sbi, struct f2fs_node *inode,
409 					const char *symname, int symlen)
410 {
411 	nid_t ino = le32_to_cpu(F2FS_NODE_FOOTER(inode)->ino);
412 	struct f2fs_summary sum;
413 	struct node_info ni;
414 	char *data_blk;
415 	block_t blkaddr = NULL_ADDR;
416 	int ret;
417 
418 	get_node_info(sbi, ino, &ni);
419 
420 	/* store into inline_data */
421 	if ((unsigned long)(symlen + 1) <= MAX_INLINE_DATA(inode)) {
422 		inode->i.i_inline |= F2FS_INLINE_DATA;
423 		inode->i.i_inline |= F2FS_DATA_EXIST;
424 		memcpy(inline_data_addr(inode), symname, symlen);
425 		return;
426 	}
427 
428 	data_blk = calloc(F2FS_BLKSIZE, 1);
429 	ASSERT(data_blk);
430 
431 	memcpy(data_blk, symname, symlen);
432 
433 	set_summary(&sum, ino, 0, ni.version);
434 	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_WARM_DATA, 0);
435 	ASSERT(!ret);
436 
437 	ret = dev_write_block(data_blk, blkaddr,
438 			      f2fs_io_type_to_rw_hint(CURSEG_WARM_DATA));
439 	ASSERT(ret >= 0);
440 
441 	inode->i.i_addr[get_extra_isize(inode)] = cpu_to_le32(blkaddr);
442 	free(data_blk);
443 }
444 
is_extension_exist(const char * s,const char * sub)445 static inline int is_extension_exist(const char *s,
446 					const char *sub)
447 {
448 	unsigned int slen = strlen(s);
449 	unsigned int  sublen = strlen(sub);
450 	int i;
451 
452 	/*
453 	 * filename format of multimedia file should be defined as:
454 	 * "filename + '.' + extension + (optional: '.' + temp extension)".
455 	 */
456 	if (slen < sublen + 2)
457 		return 0;
458 
459 	for (i = 1; i < slen - sublen; i++) {
460 		if (s[i] != '.')
461 			continue;
462 		if (!strncasecmp(s + i + 1, sub, sublen))
463 			return 1;
464 	}
465 
466 	return 0;
467 }
468 
set_file_temperature(struct f2fs_sb_info * sbi,struct f2fs_node * node_blk,const unsigned char * name)469 static void set_file_temperature(struct f2fs_sb_info *sbi,
470 				struct f2fs_node *node_blk,
471 				const unsigned char *name)
472 {
473 	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
474 	int i, cold_count, hot_count;
475 
476 	cold_count = le32_to_cpu(sbi->raw_super->extension_count);
477 	hot_count = sbi->raw_super->hot_ext_count;
478 
479 	for (i = 0; i < cold_count + hot_count; i++) {
480 		if (is_extension_exist((const char *)name,
481 					(const char *)extlist[i]))
482 			break;
483 	}
484 
485 	if (i == cold_count + hot_count)
486 		return;
487 
488 	if (i < cold_count)
489 		node_blk->i.i_advise |= FADVISE_COLD_BIT;
490 	else
491 		node_blk->i.i_advise |= FADVISE_HOT_BIT;
492 }
493 
init_inode_block(struct f2fs_sb_info * sbi,struct f2fs_node * node_blk,struct dentry * de)494 static void init_inode_block(struct f2fs_sb_info *sbi,
495 		struct f2fs_node *node_blk, struct dentry *de)
496 {
497 	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
498 	mode_t mode = de->mode;
499 	int links = 1;
500 	unsigned int size;
501 	int blocks = 1;
502 
503 	if (de->file_type == F2FS_FT_DIR) {
504 		mode |= S_IFDIR;
505 		size = F2FS_BLKSIZE;
506 		links++;
507 		blocks++;
508 	} else if (de->file_type == F2FS_FT_REG_FILE) {
509 #ifdef S_IFREG
510 		mode |= S_IFREG;
511 #else
512 		ASSERT(0);
513 #endif
514 		size = 0;
515 	} else if (de->file_type == F2FS_FT_SYMLINK) {
516 		ASSERT(de->link);
517 #ifdef S_IFLNK
518 		mode |= S_IFLNK;
519 #else
520 		ASSERT(0);
521 #endif
522 		size = strlen(de->link);
523 		if (size + 1 > MAX_INLINE_DATA(node_blk))
524 			blocks++;
525 	} else {
526 		ASSERT(0);
527 	}
528 
529 	node_blk->i.i_mode = cpu_to_le16(mode);
530 	node_blk->i.i_advise = 0;
531 	node_blk->i.i_uid = cpu_to_le32(de->uid);
532 	node_blk->i.i_gid = cpu_to_le32(de->gid);
533 	node_blk->i.i_links = cpu_to_le32(links);
534 	node_blk->i.i_size = cpu_to_le32(size);
535 	node_blk->i.i_blocks = cpu_to_le32(blocks);
536 	node_blk->i.i_atime = cpu_to_le64(de->mtime);
537 	node_blk->i.i_ctime = cpu_to_le64(de->mtime);
538 	node_blk->i.i_mtime = cpu_to_le64(de->mtime);
539 	node_blk->i.i_atime_nsec = 0;
540 	node_blk->i.i_ctime_nsec = 0;
541 	node_blk->i.i_mtime_nsec = 0;
542 	node_blk->i.i_generation = 0;
543 	if (de->file_type == F2FS_FT_DIR)
544 		node_blk->i.i_current_depth = cpu_to_le32(1);
545 	else
546 		node_blk->i.i_current_depth = cpu_to_le32(0);
547 	node_blk->i.i_xattr_nid = 0;
548 	node_blk->i.i_flags = 0;
549 	node_blk->i.i_inline = F2FS_INLINE_XATTR;
550 	node_blk->i.i_pino = cpu_to_le32(de->pino);
551 	node_blk->i.i_namelen = cpu_to_le32(de->len);
552 	memcpy(node_blk->i.i_name, de->name, de->len);
553 	node_blk->i.i_name[de->len] = 0;
554 
555 	if (c.feature & F2FS_FEATURE_EXTRA_ATTR) {
556 		node_blk->i.i_inline |= F2FS_EXTRA_ATTR;
557 		node_blk->i.i_extra_isize = cpu_to_le16(calc_extra_isize());
558 	}
559 
560 	set_file_temperature(sbi, node_blk, de->name);
561 
562 	F2FS_NODE_FOOTER(node_blk)->ino = cpu_to_le32(de->ino);
563 	F2FS_NODE_FOOTER(node_blk)->nid = cpu_to_le32(de->ino);
564 	F2FS_NODE_FOOTER(node_blk)->flag = 0;
565 	F2FS_NODE_FOOTER(node_blk)->cp_ver = ckpt->checkpoint_ver;
566 	set_cold_node(node_blk, S_ISDIR(mode));
567 
568 	if (S_ISDIR(mode)) {
569 		make_empty_dir(sbi, node_blk);
570 	} else if (S_ISLNK(mode)) {
571 		page_symlink(sbi, node_blk, de->link, size);
572 
573 		free(de->link);
574 		de->link = NULL;
575 	}
576 
577 	if (c.feature & F2FS_FEATURE_INODE_CHKSUM)
578 		node_blk->i.i_inode_checksum =
579 			cpu_to_le32(f2fs_inode_chksum(node_blk));
580 }
581 
convert_inline_dentry(struct f2fs_sb_info * sbi,struct f2fs_node * node,block_t * p_blkaddr)582 int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
583 							block_t *p_blkaddr)
584 {
585 	struct f2fs_inode *inode = &(node->i);
586 	unsigned int dir_level = node->i.i_dir_level;
587 	nid_t ino = le32_to_cpu(F2FS_NODE_FOOTER(node)->ino);
588 	char inline_data[MAX_INLINE_DATA(node)];
589 	struct dnode_of_data dn;
590 	struct f2fs_dentry_ptr d;
591 	unsigned long bit_pos = 0;
592 	int ret = 0;
593 	bool datablk_alloced = false;
594 
595 	if (!(inode->i_inline & F2FS_INLINE_DENTRY))
596 		return 0;
597 
598 	memcpy(inline_data, inline_data_addr(node), MAX_INLINE_DATA(node));
599 	memset(inline_data_addr(node), 0, MAX_INLINE_DATA(node));
600 	inode->i_inline &= ~F2FS_INLINE_DENTRY;
601 
602 	ret = update_block(sbi, node, p_blkaddr, NULL);
603 	ASSERT(ret >= 0);
604 
605 	memset(&dn, 0, sizeof(dn));
606 	if (!dir_level) {
607 		struct f2fs_dentry_block *dentry_blk;
608 		struct f2fs_dentry_ptr src, dst;
609 
610 		dentry_blk = calloc(F2FS_BLKSIZE, 1);
611 		ASSERT(dentry_blk);
612 
613 		set_new_dnode(&dn, node, NULL, ino);
614 		get_dnode_of_data(sbi, &dn, 0, ALLOC_NODE);
615 		if (dn.data_blkaddr == NULL_ADDR) {
616 			new_data_block(sbi, dentry_blk, &dn, CURSEG_HOT_DATA);
617 			datablk_alloced = true;
618 		}
619 
620 		make_dentry_ptr(&src, node, (void *)inline_data, 2);
621 		make_dentry_ptr(&dst, NULL, (void *)dentry_blk, 1);
622 
623 		 /* copy data from inline dentry block to new dentry block */
624 		memcpy(dst.bitmap, src.bitmap, src.nr_bitmap);
625 		memset(dst.bitmap + src.nr_bitmap, 0,
626 					dst.nr_bitmap - src.nr_bitmap);
627 
628 		memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
629 		memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);
630 
631 		ret = datablk_alloced ?
632 			dev_write_block(dentry_blk, dn.data_blkaddr,
633 					f2fs_io_type_to_rw_hint(CURSEG_HOT_DATA)) :
634 			update_block(sbi, dentry_blk, &dn.data_blkaddr, NULL);
635 		ASSERT(ret >= 0);
636 
637 		MSG(1, "%s: copy inline entry to block\n", __func__);
638 
639 		free(dentry_blk);
640 		return ret;
641 	}
642 
643 	make_empty_dir(sbi, node);
644 	make_dentry_ptr(&d, node, (void *)inline_data, 2);
645 
646 	while (bit_pos < (unsigned long)d.max) {
647 		struct f2fs_dir_entry *de;
648 		const unsigned char *filename;
649 		int namelen;
650 
651 		if (!test_bit_le(bit_pos, d.bitmap)) {
652 			bit_pos++;
653 			continue;
654 		}
655 
656 		de = &d.dentry[bit_pos];
657 		if (!de->name_len) {
658 			bit_pos++;
659 			continue;
660 		}
661 
662 		filename = d.filename[bit_pos];
663 		namelen = le32_to_cpu(de->name_len);
664 
665 		if (is_dot_dotdot(filename, namelen)) {
666 			bit_pos += GET_DENTRY_SLOTS(namelen);
667 			continue;
668 		}
669 
670 		ret = f2fs_add_link(sbi, node, filename, namelen,
671 				le32_to_cpu(de->ino),
672 				de->file_type, p_blkaddr, 0);
673 		if (ret)
674 			MSG(0, "Convert file \"%s\" ERR=%d\n", filename, ret);
675 		else
676 			MSG(1, "%s: add inline entry to block\n", __func__);
677 
678 		bit_pos += GET_DENTRY_SLOTS(namelen);
679 	}
680 
681 	return 0;
682 }
683 
cmp_from_devino(const void * a,const void * b)684 static int cmp_from_devino(const void *a, const void *b) {
685 	u64 devino_a = ((struct hardlink_cache_entry*) a)->from_devino;
686 	u64 devino_b = ((struct hardlink_cache_entry*) b)->from_devino;
687 
688 	return (devino_a > devino_b) - (devino_a < devino_b);
689 }
690 
f2fs_search_hardlink(struct f2fs_sb_info * sbi,struct dentry * de)691 struct hardlink_cache_entry *f2fs_search_hardlink(struct f2fs_sb_info *sbi,
692 						struct dentry *de)
693 {
694 	struct hardlink_cache_entry *find_hardlink = NULL;
695 	struct hardlink_cache_entry *found_hardlink = NULL;
696 	void *search_result;
697 
698 	/* This might be a hardlink, try to find it in the cache */
699 	find_hardlink = calloc(1, sizeof(struct hardlink_cache_entry));
700 	find_hardlink->from_devino = de->from_devino;
701 
702 	search_result = tsearch(find_hardlink, &(sbi->hardlink_cache),
703 				cmp_from_devino);
704 	ASSERT(search_result != 0);
705 
706 	found_hardlink = *(struct hardlink_cache_entry**) search_result;
707 	ASSERT(find_hardlink->from_devino == found_hardlink->from_devino);
708 
709 	/* If it was already in the cache, free the entry we just created */
710 	if (found_hardlink != find_hardlink)
711 		free(find_hardlink);
712 
713 	return found_hardlink;
714 }
715 
f2fs_create(struct f2fs_sb_info * sbi,struct dentry * de)716 int f2fs_create(struct f2fs_sb_info *sbi, struct dentry *de)
717 {
718 	struct f2fs_node *parent, *child;
719 	struct hardlink_cache_entry *found_hardlink = NULL;
720 	struct node_info ni, hardlink_ni;
721 	struct f2fs_summary sum;
722 	block_t blkaddr = NULL_ADDR;
723 	int ret;
724 	bool nodeblk_alloced = false;
725 
726 	/* Find if there is a */
727 	get_node_info(sbi, de->pino, &ni);
728 	if (ni.blk_addr == NULL_ADDR) {
729 		MSG(0, "No parent directory pino=%x\n", de->pino);
730 		return -1;
731 	}
732 
733 	if (de->from_devino)
734 		found_hardlink = f2fs_search_hardlink(sbi, de);
735 
736 	parent = calloc(F2FS_BLKSIZE, 1);
737 	ASSERT(parent);
738 
739 	ret = dev_read_block(parent, ni.blk_addr);
740 	ASSERT(ret >= 0);
741 
742 	/* Must convert inline dentry before the following opertions */
743 	ret = convert_inline_dentry(sbi, parent, &ni.blk_addr);
744 	if (ret) {
745 		MSG(0, "Convert inline dentry for pino=%x failed.\n", de->pino);
746 		ret = -1;
747 		goto free_parent_dir;
748 	}
749 
750 	ret = f2fs_find_entry(sbi, parent, de);
751 	if (ret) {
752 		MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
753 					de->name, de->pino, ret);
754 		if (de->file_type == F2FS_FT_REG_FILE)
755 			de->ino = 0;
756 		ret = 0;
757 		goto free_parent_dir;
758 	}
759 
760 	child = calloc(F2FS_BLKSIZE, 1);
761 	ASSERT(child);
762 
763 	if (found_hardlink && found_hardlink->to_ino) {
764 		/*
765 		 * If we found this devino in the cache, we're creating a
766 		 * hard link.
767 		 */
768 		get_node_info(sbi, found_hardlink->to_ino, &hardlink_ni);
769 		if (hardlink_ni.blk_addr == NULL_ADDR) {
770 			MSG(1, "No original inode for hard link to_ino=%x\n",
771 				found_hardlink->to_ino);
772 			ret = -1;
773 			goto free_child_dir;
774 		}
775 
776 		/* Use previously-recorded inode */
777 		de->ino = found_hardlink->to_ino;
778 		blkaddr = hardlink_ni.blk_addr;
779 		MSG(1, "Info: Creating \"%s\" as hard link to inode %d\n",
780 				de->path, de->ino);
781 	} else {
782 		f2fs_alloc_nid(sbi, &de->ino);
783 	}
784 
785 	init_inode_block(sbi, child, de);
786 
787 	ret = f2fs_add_link(sbi, parent, child->i.i_name,
788 				le32_to_cpu(child->i.i_namelen),
789 				le32_to_cpu(F2FS_NODE_FOOTER(child)->ino),
790 				map_de_type(le16_to_cpu(child->i.i_mode)),
791 				&ni.blk_addr, 1);
792 	if (ret) {
793 		MSG(0, "Skip the existing \"%s\" pino=%x ERR=%d\n",
794 					de->name, de->pino, ret);
795 		ret = 0;
796 		goto free_child_dir;
797 	}
798 
799 	if (found_hardlink) {
800 		if (!found_hardlink->to_ino) {
801 			MSG(2, "Adding inode %d from %s to hardlink cache\n",
802 				de->ino, de->path);
803 			found_hardlink->to_ino = de->ino;
804 		} else {
805 			/* Replace child with original block */
806 			free(child);
807 
808 			child = calloc(F2FS_BLKSIZE, 1);
809 			ASSERT(child);
810 
811 			ret = dev_read_block(child, blkaddr);
812 			ASSERT(ret >= 0);
813 
814 			/* Increment links and skip to writing block */
815 			child->i.i_links = cpu_to_le32(
816 					le32_to_cpu(child->i.i_links) + 1);
817 			MSG(2, "Number of links on inode %d is now %d\n",
818 				de->ino, le32_to_cpu(child->i.i_links));
819 			goto write_child_dir;
820 		}
821 	}
822 
823 	/* write child */
824 	set_summary(&sum, de->ino, 0, ni.version);
825 	ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1);
826 	nodeblk_alloced = true;
827 	ASSERT(!ret);
828 
829 	/* update nat info */
830 	update_nat_blkaddr(sbi, de->ino, de->ino, blkaddr);
831 
832 write_child_dir:
833 	ret = nodeblk_alloced ? dev_write_block(child, blkaddr,
834 			f2fs_io_type_to_rw_hint(CURSEG_HOT_NODE)) :
835 		update_block(sbi, child, &blkaddr, NULL);
836 	ASSERT(ret >= 0);
837 
838 	update_free_segments(sbi);
839 	MSG(1, "Info: Create %s -> %s\n"
840 		"  -- ino=%x, type=%x, mode=%x, uid=%x, "
841 		"gid=%x, cap=%"PRIx64", size=%lu, link=%u "
842 		"blocks=%"PRIx64" pino=%x\n",
843 		de->full_path, de->path,
844 		de->ino, de->file_type, de->mode,
845 		de->uid, de->gid, de->capabilities, de->size,
846 		le32_to_cpu(child->i.i_links),
847 		le64_to_cpu(child->i.i_blocks),
848 		de->pino);
849 free_child_dir:
850 	free(child);
851 free_parent_dir:
852 	free(parent);
853 	return ret;
854 }
855 
f2fs_mkdir(struct f2fs_sb_info * sbi,struct dentry * de)856 int f2fs_mkdir(struct f2fs_sb_info *sbi, struct dentry *de)
857 {
858 	return f2fs_create(sbi, de);
859 }
860 
f2fs_symlink(struct f2fs_sb_info * sbi,struct dentry * de)861 int f2fs_symlink(struct f2fs_sb_info *sbi, struct dentry *de)
862 {
863 	return f2fs_create(sbi, de);
864 }
865 
f2fs_find_path(struct f2fs_sb_info * sbi,char * path,nid_t * ino)866 int f2fs_find_path(struct f2fs_sb_info *sbi, char *path, nid_t *ino)
867 {
868 	struct f2fs_node *parent;
869 	struct node_info ni;
870 	struct dentry de;
871 	int err = 0;
872 	int ret;
873 	char *p;
874 
875 	if (path[0] != '/')
876 		return -ENOENT;
877 
878 	*ino = F2FS_ROOT_INO(sbi);
879 	parent = calloc(F2FS_BLKSIZE, 1);
880 	ASSERT(parent);
881 
882 	p = strtok(path, "/");
883 	while (p) {
884 		de.name = (const u8 *)p;
885 		de.len = strlen(p);
886 
887 		get_node_info(sbi, *ino, &ni);
888 		if (ni.blk_addr == NULL_ADDR) {
889 			err = -ENOENT;
890 			goto err;
891 		}
892 		ret = dev_read_block(parent, ni.blk_addr);
893 		ASSERT(ret >= 0);
894 
895 		ret = f2fs_find_entry(sbi, parent, &de);
896 		if (!ret) {
897 			err = -ENOENT;
898 			goto err;
899 		}
900 
901 		*ino = de.ino;
902 		p = strtok(NULL, "/");
903 	}
904 err:
905 	free(parent);
906 	return err;
907 }
908