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