• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * libf2fs.c
3  *
4  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5  *             http://www.samsung.com/
6  *
7  * Dual licensed under the GPL or LGPL version 2 licenses.
8  */
9 #define _LARGEFILE64_SOURCE
10 #define _FILE_OFFSET_BITS 64
11 
12 #include <f2fs_fs.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <libgen.h>
20 #ifdef HAVE_MNTENT_H
21 #include <mntent.h>
22 #endif
23 #include <time.h>
24 #include <sys/stat.h>
25 #ifndef ANDROID_WINDOWS_HOST
26 #include <sys/mount.h>
27 #include <sys/ioctl.h>
28 #endif
29 #ifdef HAVE_SYS_SYSMACROS_H
30 #include <sys/sysmacros.h>
31 #endif
32 #ifdef HAVE_SYS_UTSNAME_H
33 #include <sys/utsname.h>
34 #endif
35 #ifndef WITH_ANDROID
36 #ifdef HAVE_SCSI_SG_H
37 #include <scsi/sg.h>
38 #endif
39 #endif
40 #ifdef HAVE_LINUX_HDREG_H
41 #include <linux/hdreg.h>
42 #endif
43 #ifdef HAVE_LINUX_LIMITS_H
44 #include <linux/limits.h>
45 #endif
46 
47 #ifndef WITH_ANDROID
48 /* SCSI command for standard inquiry*/
49 #define MODELINQUIRY	0x12,0x00,0x00,0x00,0x4A,0x00
50 #endif
51 
52 #ifndef ANDROID_WINDOWS_HOST /* O_BINARY is windows-specific flag */
53 #define O_BINARY 0
54 #else
55 /* On Windows, wchar_t is 8 bit sized and it causes compilation errors. */
56 #define wchar_t	int
57 #endif
58 
59 /*
60  * UTF conversion codes are Copied from exfat tools.
61  */
utf8_to_wchar(const char * input,wchar_t * wc,size_t insize)62 static const char *utf8_to_wchar(const char *input, wchar_t *wc,
63 		size_t insize)
64 {
65 	if ((input[0] & 0x80) == 0 && insize >= 1) {
66 		*wc = (wchar_t) input[0];
67 		return input + 1;
68 	}
69 	if ((input[0] & 0xe0) == 0xc0 && insize >= 2) {
70 		*wc = (((wchar_t) input[0] & 0x1f) << 6) |
71 		       ((wchar_t) input[1] & 0x3f);
72 		return input + 2;
73 	}
74 	if ((input[0] & 0xf0) == 0xe0 && insize >= 3) {
75 		*wc = (((wchar_t) input[0] & 0x0f) << 12) |
76 		      (((wchar_t) input[1] & 0x3f) << 6) |
77 		       ((wchar_t) input[2] & 0x3f);
78 		return input + 3;
79 	}
80 	if ((input[0] & 0xf8) == 0xf0 && insize >= 4) {
81 		*wc = (((wchar_t) input[0] & 0x07) << 18) |
82 		      (((wchar_t) input[1] & 0x3f) << 12) |
83 		      (((wchar_t) input[2] & 0x3f) << 6) |
84 		       ((wchar_t) input[3] & 0x3f);
85 		return input + 4;
86 	}
87 	if ((input[0] & 0xfc) == 0xf8 && insize >= 5) {
88 		*wc = (((wchar_t) input[0] & 0x03) << 24) |
89 		      (((wchar_t) input[1] & 0x3f) << 18) |
90 		      (((wchar_t) input[2] & 0x3f) << 12) |
91 		      (((wchar_t) input[3] & 0x3f) << 6) |
92 		       ((wchar_t) input[4] & 0x3f);
93 		return input + 5;
94 	}
95 	if ((input[0] & 0xfe) == 0xfc && insize >= 6) {
96 		*wc = (((wchar_t) input[0] & 0x01) << 30) |
97 		      (((wchar_t) input[1] & 0x3f) << 24) |
98 		      (((wchar_t) input[2] & 0x3f) << 18) |
99 		      (((wchar_t) input[3] & 0x3f) << 12) |
100 		      (((wchar_t) input[4] & 0x3f) << 6) |
101 		       ((wchar_t) input[5] & 0x3f);
102 		return input + 6;
103 	}
104 	return NULL;
105 }
106 
wchar_to_utf16(u_int16_t * output,wchar_t wc,size_t outsize)107 static u_int16_t *wchar_to_utf16(u_int16_t *output, wchar_t wc, size_t outsize)
108 {
109 	if (wc <= 0xffff) {
110 		if (outsize == 0)
111 			return NULL;
112 		output[0] = cpu_to_le16(wc);
113 		return output + 1;
114 	}
115 	if (outsize < 2)
116 		return NULL;
117 	wc -= 0x10000;
118 	output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff));
119 	output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff));
120 	return output + 2;
121 }
122 
utf8_to_utf16(u_int16_t * output,const char * input,size_t outsize,size_t insize)123 int utf8_to_utf16(u_int16_t *output, const char *input, size_t outsize,
124 		size_t insize)
125 {
126 	const char *inp = input;
127 	u_int16_t *outp = output;
128 	wchar_t wc;
129 
130 	while ((size_t)(inp - input) < insize && *inp) {
131 		inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
132 		if (inp == NULL) {
133 			DBG(0, "illegal UTF-8 sequence\n");
134 			return -EILSEQ;
135 		}
136 		outp = wchar_to_utf16(outp, wc, outsize - (outp - output));
137 		if (outp == NULL) {
138 			DBG(0, "name is too long\n");
139 			return -ENAMETOOLONG;
140 		}
141 	}
142 	*outp = cpu_to_le16(0);
143 	return 0;
144 }
145 
utf16_to_wchar(const u_int16_t * input,wchar_t * wc,size_t insize)146 static const u_int16_t *utf16_to_wchar(const u_int16_t *input, wchar_t *wc,
147 		size_t insize)
148 {
149 	if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) {
150 		if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00)
151 			return NULL;
152 		*wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10);
153 		*wc |= (le16_to_cpu(input[1]) & 0x3ff);
154 		*wc += 0x10000;
155 		return input + 2;
156 	} else {
157 		*wc = le16_to_cpu(*input);
158 		return input + 1;
159 	}
160 }
161 
wchar_to_utf8(char * output,wchar_t wc,size_t outsize)162 static char *wchar_to_utf8(char *output, wchar_t wc, size_t outsize)
163 {
164 	if (wc <= 0x7f) {
165 		if (outsize < 1)
166 			return NULL;
167 		*output++ = (char) wc;
168 	} else if (wc <= 0x7ff) {
169 		if (outsize < 2)
170 			return NULL;
171 		*output++ = 0xc0 | (wc >> 6);
172 		*output++ = 0x80 | (wc & 0x3f);
173 	} else if (wc <= 0xffff) {
174 		if (outsize < 3)
175 			return NULL;
176 		*output++ = 0xe0 | (wc >> 12);
177 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
178 		*output++ = 0x80 | (wc & 0x3f);
179 	} else if (wc <= 0x1fffff) {
180 		if (outsize < 4)
181 			return NULL;
182 		*output++ = 0xf0 | (wc >> 18);
183 		*output++ = 0x80 | ((wc >> 12) & 0x3f);
184 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
185 		*output++ = 0x80 | (wc & 0x3f);
186 	} else if (wc <= 0x3ffffff) {
187 		if (outsize < 5)
188 			return NULL;
189 		*output++ = 0xf8 | (wc >> 24);
190 		*output++ = 0x80 | ((wc >> 18) & 0x3f);
191 		*output++ = 0x80 | ((wc >> 12) & 0x3f);
192 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
193 		*output++ = 0x80 | (wc & 0x3f);
194 	} else if (wc <= 0x7fffffff) {
195 		if (outsize < 6)
196 			return NULL;
197 		*output++ = 0xfc | (wc >> 30);
198 		*output++ = 0x80 | ((wc >> 24) & 0x3f);
199 		*output++ = 0x80 | ((wc >> 18) & 0x3f);
200 		*output++ = 0x80 | ((wc >> 12) & 0x3f);
201 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
202 		*output++ = 0x80 | (wc & 0x3f);
203 	} else
204 		return NULL;
205 
206 	return output;
207 }
208 
utf16_to_utf8(char * output,const u_int16_t * input,size_t outsize,size_t insize)209 int utf16_to_utf8(char *output, const u_int16_t *input, size_t outsize,
210 		size_t insize)
211 {
212 	const u_int16_t *inp = input;
213 	char *outp = output;
214 	wchar_t wc;
215 
216 	while ((size_t)(inp - input) < insize && le16_to_cpu(*inp)) {
217 		inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
218 		if (inp == NULL) {
219 			DBG(0, "illegal UTF-16 sequence\n");
220 			return -EILSEQ;
221 		}
222 		outp = wchar_to_utf8(outp, wc, outsize - (outp - output));
223 		if (outp == NULL) {
224 			DBG(0, "name is too long\n");
225 			return -ENAMETOOLONG;
226 		}
227 	}
228 	*outp = '\0';
229 	return 0;
230 }
231 
log_base_2(u_int32_t num)232 int log_base_2(u_int32_t num)
233 {
234 	int ret = 0;
235 	if (num <= 0 || (num & (num - 1)) != 0)
236 		return -1;
237 
238 	while (num >>= 1)
239 		ret++;
240 	return ret;
241 }
242 
243 /*
244  * f2fs bit operations
245  */
246 static const int bits_in_byte[256] = {
247 	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
248 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
249 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
250 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
251 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
252 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
253 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
254 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
255 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
256 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
257 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
258 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
259 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
260 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
261 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
262 	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
263 };
264 
get_bits_in_byte(unsigned char n)265 int get_bits_in_byte(unsigned char n)
266 {
267 	return bits_in_byte[n];
268 }
269 
test_and_set_bit_le(u32 nr,u8 * addr)270 int test_and_set_bit_le(u32 nr, u8 *addr)
271 {
272 	int mask, retval;
273 
274 	addr += nr >> 3;
275 	mask = 1 << ((nr & 0x07));
276 	retval = mask & *addr;
277 	*addr |= mask;
278 	return retval;
279 }
280 
test_and_clear_bit_le(u32 nr,u8 * addr)281 int test_and_clear_bit_le(u32 nr, u8 *addr)
282 {
283 	int mask, retval;
284 
285 	addr += nr >> 3;
286 	mask = 1 << ((nr & 0x07));
287 	retval = mask & *addr;
288 	*addr &= ~mask;
289 	return retval;
290 }
291 
test_bit_le(u32 nr,const u8 * addr)292 int test_bit_le(u32 nr, const u8 *addr)
293 {
294 	return ((1 << (nr & 7)) & (addr[nr >> 3]));
295 }
296 
f2fs_test_bit(unsigned int nr,const char * p)297 int f2fs_test_bit(unsigned int nr, const char *p)
298 {
299 	int mask;
300 	char *addr = (char *)p;
301 
302 	addr += (nr >> 3);
303 	mask = 1 << (7 - (nr & 0x07));
304 	return (mask & *addr) != 0;
305 }
306 
f2fs_set_bit(unsigned int nr,char * addr)307 int f2fs_set_bit(unsigned int nr, char *addr)
308 {
309 	int mask;
310 	int ret;
311 
312 	addr += (nr >> 3);
313 	mask = 1 << (7 - (nr & 0x07));
314 	ret = mask & *addr;
315 	*addr |= mask;
316 	return ret;
317 }
318 
f2fs_clear_bit(unsigned int nr,char * addr)319 int f2fs_clear_bit(unsigned int nr, char *addr)
320 {
321 	int mask;
322 	int ret;
323 
324 	addr += (nr >> 3);
325 	mask = 1 << (7 - (nr & 0x07));
326 	ret = mask & *addr;
327 	*addr &= ~mask;
328 	return ret;
329 }
330 
__ffs(u8 word)331 static inline u64 __ffs(u8 word)
332 {
333 	int num = 0;
334 
335 	if ((word & 0xf) == 0) {
336 		num += 4;
337 		word >>= 4;
338 	}
339 	if ((word & 0x3) == 0) {
340 		num += 2;
341 		word >>= 2;
342 	}
343 	if ((word & 0x1) == 0)
344 		num += 1;
345 	return num;
346 }
347 
348 /* Copied from linux/lib/find_bit.c */
349 #define BITMAP_FIRST_BYTE_MASK(start) (0xff << ((start) & (BITS_PER_BYTE - 1)))
350 
_find_next_bit_le(const u8 * addr,u64 nbits,u64 start,char invert)351 static u64 _find_next_bit_le(const u8 *addr, u64 nbits, u64 start, char invert)
352 {
353 	u8 tmp;
354 
355 	if (!nbits || start >= nbits)
356 		return nbits;
357 
358 	tmp = addr[start / BITS_PER_BYTE] ^ invert;
359 
360 	/* Handle 1st word. */
361 	tmp &= BITMAP_FIRST_BYTE_MASK(start);
362 	start = round_down(start, BITS_PER_BYTE);
363 
364 	while (!tmp) {
365 		start += BITS_PER_BYTE;
366 		if (start >= nbits)
367 			return nbits;
368 
369 		tmp = addr[start / BITS_PER_BYTE] ^ invert;
370 	}
371 
372 	return min(start + __ffs(tmp), nbits);
373 }
374 
find_next_bit_le(const u8 * addr,u64 size,u64 offset)375 u64 find_next_bit_le(const u8 *addr, u64 size, u64 offset)
376 {
377 	return _find_next_bit_le(addr, size, offset, 0);
378 }
379 
380 
find_next_zero_bit_le(const u8 * addr,u64 size,u64 offset)381 u64 find_next_zero_bit_le(const u8 *addr, u64 size, u64 offset)
382 {
383 	return _find_next_bit_le(addr, size, offset, 0xff);
384 }
385 
386 /*
387  * Hashing code adapted from ext3
388  */
389 #define DELTA 0x9E3779B9
390 
TEA_transform(unsigned int buf[4],unsigned int const in[])391 static void TEA_transform(unsigned int buf[4], unsigned int const in[])
392 {
393 	__u32 sum = 0;
394 	__u32 b0 = buf[0], b1 = buf[1];
395 	__u32 a = in[0], b = in[1], c = in[2], d = in[3];
396 	int     n = 16;
397 
398 	do {
399 		sum += DELTA;
400 		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
401 		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
402 	} while (--n);
403 
404 	buf[0] += b0;
405 	buf[1] += b1;
406 
407 }
408 
str2hashbuf(const unsigned char * msg,int len,unsigned int * buf,int num)409 static void str2hashbuf(const unsigned char *msg, int len,
410 					unsigned int *buf, int num)
411 {
412 	unsigned pad, val;
413 	int i;
414 
415 	pad = (__u32)len | ((__u32)len << 8);
416 	pad |= pad << 16;
417 
418 	val = pad;
419 	if (len > num * 4)
420 		len = num * 4;
421 	for (i = 0; i < len; i++) {
422 		if ((i % 4) == 0)
423 			val = pad;
424 		val = msg[i] + (val << 8);
425 		if ((i % 4) == 3) {
426 			*buf++ = val;
427 			val = pad;
428 			num--;
429 		}
430 	}
431 	if (--num >= 0)
432 		*buf++ = val;
433 	while (--num >= 0)
434 		*buf++ = pad;
435 
436 }
437 
438 /**
439  * Return hash value of directory entry
440  * @param name          dentry name
441  * @param len           name lenth
442  * @return              return on success hash value, errno on failure
443  */
__f2fs_dentry_hash(const unsigned char * name,int len)444 static f2fs_hash_t __f2fs_dentry_hash(const unsigned char *name, int len)/* Need update */
445 {
446 	__u32 hash;
447 	f2fs_hash_t	f2fs_hash;
448 	const unsigned char	*p;
449 	__u32 in[8], buf[4];
450 
451 	/* special hash codes for special dentries */
452 	if ((len <= 2) && (name[0] == '.') &&
453 		(name[1] == '.' || name[1] == '\0'))
454 		return 0;
455 
456 	/* Initialize the default seed for the hash checksum functions */
457 	buf[0] = 0x67452301;
458 	buf[1] = 0xefcdab89;
459 	buf[2] = 0x98badcfe;
460 	buf[3] = 0x10325476;
461 
462 	p = name;
463 	while (1) {
464 		str2hashbuf(p, len, in, 4);
465 		TEA_transform(buf, in);
466 		p += 16;
467 		if (len <= 16)
468 			break;
469 		len -= 16;
470 	}
471 	hash = buf[0];
472 
473 	f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
474 	return f2fs_hash;
475 }
476 
f2fs_dentry_hash(int encoding,int casefolded,const unsigned char * name,int len)477 f2fs_hash_t f2fs_dentry_hash(int encoding, int casefolded,
478                              const unsigned char *name, int len)
479 {
480 	const struct f2fs_nls_table *table = f2fs_load_nls_table(encoding);
481 	int r, dlen;
482 	unsigned char *buff;
483 
484 	if (len && casefolded) {
485 		buff = malloc(sizeof(char) * PATH_MAX);
486 		if (!buff)
487 			return -ENOMEM;
488 		dlen = table->ops->casefold(table, name, len, buff, PATH_MAX);
489 		if (dlen < 0) {
490 			free(buff);
491 			goto opaque_seq;
492 		}
493 		r = __f2fs_dentry_hash(buff, dlen);
494 
495 		free(buff);
496 		return r;
497 	}
498 opaque_seq:
499 	return __f2fs_dentry_hash(name, len);
500 }
501 
addrs_per_inode(struct f2fs_inode * i)502 unsigned int addrs_per_inode(struct f2fs_inode *i)
503 {
504 	unsigned int addrs = CUR_ADDRS_PER_INODE(i) - get_inline_xattr_addrs(i);
505 
506 	if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
507 			!(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
508 		return addrs;
509 	return ALIGN_DOWN(addrs, 1 << i->i_log_cluster_size);
510 }
511 
addrs_per_block(struct f2fs_inode * i)512 unsigned int addrs_per_block(struct f2fs_inode *i)
513 {
514 	if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
515 			!(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
516 		return DEF_ADDRS_PER_BLOCK;
517 	return ALIGN_DOWN(DEF_ADDRS_PER_BLOCK, 1 << i->i_log_cluster_size);
518 }
519 
f2fs_max_file_offset(struct f2fs_inode * i)520 unsigned int f2fs_max_file_offset(struct f2fs_inode *i)
521 {
522 	if (!LINUX_S_ISREG(le16_to_cpu(i->i_mode)) ||
523 			!(le32_to_cpu(i->i_flags) & F2FS_COMPR_FL))
524 		return le64_to_cpu(i->i_size);
525 	return ALIGN_UP(le64_to_cpu(i->i_size), 1 << i->i_log_cluster_size);
526 }
527 
528 /*
529  * CRC32
530  */
531 #define CRCPOLY_LE 0xedb88320
532 
f2fs_cal_crc32(u_int32_t crc,void * buf,int len)533 u_int32_t f2fs_cal_crc32(u_int32_t crc, void *buf, int len)
534 {
535 	int i;
536 	unsigned char *p = (unsigned char *)buf;
537 	while (len--) {
538 		crc ^= *p++;
539 		for (i = 0; i < 8; i++)
540 			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
541 	}
542 	return crc;
543 }
544 
f2fs_crc_valid(u_int32_t blk_crc,void * buf,int len)545 int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
546 {
547 	u_int32_t cal_crc = 0;
548 
549 	cal_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, buf, len);
550 
551 	if (cal_crc != blk_crc)	{
552 		DBG(0,"CRC validation failed: cal_crc = %u, "
553 			"blk_crc = %u buff_size = 0x%x\n",
554 			cal_crc, blk_crc, len);
555 		return -1;
556 	}
557 	return 0;
558 }
559 
f2fs_inode_chksum(struct f2fs_node * node)560 __u32 f2fs_inode_chksum(struct f2fs_node *node)
561 {
562 	struct f2fs_inode *ri = &node->i;
563 	__le32 ino = node->footer.ino;
564 	__le32 gen = ri->i_generation;
565 	__u32 chksum, chksum_seed;
566 	__u32 dummy_cs = 0;
567 	unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
568 	unsigned int cs_size = sizeof(dummy_cs);
569 
570 	chksum = f2fs_cal_crc32(c.chksum_seed, (__u8 *)&ino,
571 							sizeof(ino));
572 	chksum_seed = f2fs_cal_crc32(chksum, (__u8 *)&gen, sizeof(gen));
573 
574 	chksum = f2fs_cal_crc32(chksum_seed, (__u8 *)ri, offset);
575 	chksum = f2fs_cal_crc32(chksum, (__u8 *)&dummy_cs, cs_size);
576 	offset += cs_size;
577 	chksum = f2fs_cal_crc32(chksum, (__u8 *)ri + offset,
578 						F2FS_BLKSIZE - offset);
579 	return chksum;
580 }
581 
f2fs_checkpoint_chksum(struct f2fs_checkpoint * cp)582 __u32 f2fs_checkpoint_chksum(struct f2fs_checkpoint *cp)
583 {
584 	unsigned int chksum_ofs = le32_to_cpu(cp->checksum_offset);
585 	__u32 chksum;
586 
587 	chksum = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, chksum_ofs);
588 	if (chksum_ofs < CP_CHKSUM_OFFSET) {
589 		chksum_ofs += sizeof(chksum);
590 		chksum = f2fs_cal_crc32(chksum, (__u8 *)cp + chksum_ofs,
591 						F2FS_BLKSIZE - chksum_ofs);
592 	}
593 	return chksum;
594 }
595 
write_inode(struct f2fs_node * inode,u64 blkaddr)596 int write_inode(struct f2fs_node *inode, u64 blkaddr)
597 {
598 	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
599 		inode->i.i_inode_checksum =
600 			cpu_to_le32(f2fs_inode_chksum(inode));
601 	return dev_write_block(inode, blkaddr);
602 }
603 
604 /*
605  * try to identify the root device
606  */
get_rootdev()607 char *get_rootdev()
608 {
609 #if defined(ANDROID_WINDOWS_HOST) || defined(WITH_ANDROID)
610 	return NULL;
611 #else
612 	struct stat sb;
613 	int fd, ret;
614 	char buf[PATH_MAX + 1];
615 	char *uevent, *ptr;
616 	char *rootdev;
617 
618 	if (stat("/", &sb) == -1)
619 		return NULL;
620 
621 	snprintf(buf, PATH_MAX, "/sys/dev/block/%u:%u/uevent",
622 		major(sb.st_dev), minor(sb.st_dev));
623 
624 	fd = open(buf, O_RDONLY);
625 
626 	if (fd < 0)
627 		return NULL;
628 
629 	ret = lseek(fd, (off_t)0, SEEK_END);
630 	(void)lseek(fd, (off_t)0, SEEK_SET);
631 
632 	if (ret == -1) {
633 		close(fd);
634 		return NULL;
635 	}
636 
637 	uevent = malloc(ret + 1);
638 	ASSERT(uevent);
639 
640 	uevent[ret] = '\0';
641 
642 	ret = read(fd, uevent, ret);
643 	close(fd);
644 
645 	ptr = strstr(uevent, "DEVNAME");
646 	if (!ptr)
647 		goto out_free;
648 
649 	ret = sscanf(ptr, "DEVNAME=%s\n", buf);
650 	if (strlen(buf) == 0)
651 		goto out_free;
652 
653 	ret = strlen(buf) + 5;
654 	rootdev = malloc(ret + 1);
655 	if (!rootdev)
656 		goto out_free;
657 	rootdev[ret] = '\0';
658 
659 	snprintf(rootdev, ret + 1, "/dev/%s", buf);
660 	free(uevent);
661 	return rootdev;
662 
663 out_free:
664 	free(uevent);
665 	return NULL;
666 #endif
667 }
668 
669 /*
670  * device information
671  */
f2fs_init_configuration(void)672 void f2fs_init_configuration(void)
673 {
674 	int i;
675 
676 	memset(&c, 0, sizeof(struct f2fs_configuration));
677 	c.ndevs = 1;
678 	c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
679 	c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
680 	c.wanted_total_sectors = -1;
681 	c.wanted_sector_size = -1;
682 #ifndef WITH_ANDROID
683 	c.preserve_limits = 1;
684 	c.no_kernel_check = 1;
685 #else
686 	c.no_kernel_check = 0;
687 #endif
688 
689 	for (i = 0; i < MAX_DEVICES; i++) {
690 		c.devices[i].fd = -1;
691 		c.devices[i].sector_size = DEFAULT_SECTOR_SIZE;
692 		c.devices[i].end_blkaddr = -1;
693 		c.devices[i].zoned_model = F2FS_ZONED_NONE;
694 	}
695 
696 	/* calculated by overprovision ratio */
697 	c.segs_per_sec = 1;
698 	c.secs_per_zone = 1;
699 	c.segs_per_zone = 1;
700 	c.vol_label = "";
701 	c.trim = 1;
702 	c.kd = -1;
703 	c.fixed_time = -1;
704 	c.s_encoding = 0;
705 	c.s_encoding_flags = 0;
706 
707 	/* default root owner */
708 	c.root_uid = getuid();
709 	c.root_gid = getgid();
710 }
711 
f2fs_dev_is_writable(void)712 int f2fs_dev_is_writable(void)
713 {
714 	return !c.ro || c.force;
715 }
716 
717 #ifdef HAVE_SETMNTENT
is_mounted(const char * mpt,const char * device)718 static int is_mounted(const char *mpt, const char *device)
719 {
720 	FILE *file = NULL;
721 	struct mntent *mnt = NULL;
722 
723 	file = setmntent(mpt, "r");
724 	if (file == NULL)
725 		return 0;
726 
727 	while ((mnt = getmntent(file)) != NULL) {
728 		if (!strcmp(device, mnt->mnt_fsname)) {
729 #ifdef MNTOPT_RO
730 			if (hasmntopt(mnt, MNTOPT_RO))
731 				c.ro = 1;
732 #endif
733 			break;
734 		}
735 	}
736 	endmntent(file);
737 	return mnt ? 1 : 0;
738 }
739 #endif
740 
f2fs_dev_is_umounted(char * path)741 int f2fs_dev_is_umounted(char *path)
742 {
743 #ifdef ANDROID_WINDOWS_HOST
744 	return 0;
745 #else
746 	struct stat *st_buf;
747 	int is_rootdev = 0;
748 	int ret = 0;
749 	char *rootdev_name = get_rootdev();
750 
751 	if (rootdev_name) {
752 		if (!strcmp(path, rootdev_name))
753 			is_rootdev = 1;
754 		free(rootdev_name);
755 	}
756 
757 	/*
758 	 * try with /proc/mounts fist to detect RDONLY.
759 	 * f2fs_stop_checkpoint makes RO in /proc/mounts while RW in /etc/mtab.
760 	 */
761 #ifdef __linux__
762 	ret = is_mounted("/proc/mounts", path);
763 	if (ret) {
764 		MSG(0, "Info: Mounted device!\n");
765 		return -1;
766 	}
767 #endif
768 #if defined(MOUNTED) || defined(_PATH_MOUNTED)
769 #ifndef MOUNTED
770 #define MOUNTED _PATH_MOUNTED
771 #endif
772 	ret = is_mounted(MOUNTED, path);
773 	if (ret) {
774 		MSG(0, "Info: Mounted device!\n");
775 		return -1;
776 	}
777 #endif
778 	/*
779 	 * If we are supposed to operate on the root device, then
780 	 * also check the mounts for '/dev/root', which sometimes
781 	 * functions as an alias for the root device.
782 	 */
783 	if (is_rootdev) {
784 #ifdef __linux__
785 		ret = is_mounted("/proc/mounts", "/dev/root");
786 		if (ret) {
787 			MSG(0, "Info: Mounted device!\n");
788 			return -1;
789 		}
790 #endif
791 	}
792 
793 	/*
794 	 * If f2fs is umounted with -l, the process can still use
795 	 * the file system. In this case, we should not format.
796 	 */
797 	st_buf = malloc(sizeof(struct stat));
798 	ASSERT(st_buf);
799 
800 	if (stat(path, st_buf) == 0 && S_ISBLK(st_buf->st_mode)) {
801 		int fd = open(path, O_RDONLY | O_EXCL);
802 
803 		if (fd >= 0) {
804 			close(fd);
805 		} else if (errno == EBUSY) {
806 			MSG(0, "\tError: In use by the system!\n");
807 			free(st_buf);
808 			return -1;
809 		}
810 	}
811 	free(st_buf);
812 	return ret;
813 #endif
814 }
815 
f2fs_devs_are_umounted(void)816 int f2fs_devs_are_umounted(void)
817 {
818 	int i;
819 
820 	for (i = 0; i < c.ndevs; i++)
821 		if (f2fs_dev_is_umounted((char *)c.devices[i].path))
822 			return -1;
823 	return 0;
824 }
825 
get_kernel_version(__u8 * version)826 void get_kernel_version(__u8 *version)
827 {
828 	int i;
829 	for (i = 0; i < VERSION_NAME_LEN; i++) {
830 		if (version[i] == '\n')
831 			break;
832 	}
833 	memset(version + i, 0, VERSION_LEN + 1 - i);
834 }
835 
get_kernel_uname_version(__u8 * version)836 void get_kernel_uname_version(__u8 *version)
837 {
838 #ifdef HAVE_SYS_UTSNAME_H
839 	struct utsname buf;
840 
841 	memset(version, 0, VERSION_LEN);
842 	if (uname(&buf))
843 		return;
844 
845 #if defined(WITH_KERNEL_VERSION)
846 	snprintf((char *)version,
847 		VERSION_NAME_LEN, "%s %s", buf.release, buf.version);
848 #else
849 	snprintf((char *)version,
850 		VERSION_NAME_LEN, "%s", buf.release);
851 #endif
852 #else
853 	memset(version, 0, VERSION_LEN);
854 #endif
855 }
856 
857 #if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
858 #define BLKGETSIZE	_IO(0x12,96)
859 #endif
860 
861 #if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
862 #define BLKGETSIZE64	_IOR(0x12,114, size_t)
863 #endif
864 
865 #if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
866 #define BLKSSZGET	_IO(0x12,104)
867 #endif
868 
869 #if defined(__APPLE__)
870 #include <sys/disk.h>
871 #define BLKGETSIZE	DKIOCGETBLOCKCOUNT
872 #define BLKSSZGET	DKIOCGETBLOCKCOUNT
873 #endif /* APPLE_DARWIN */
874 
875 #ifndef ANDROID_WINDOWS_HOST
open_check_fs(char * path,int flag)876 static int open_check_fs(char *path, int flag)
877 {
878 	if (c.func != DUMP && (c.func != FSCK || c.fix_on || c.auto_fix))
879 		return -1;
880 
881 	/* allow to open ro */
882 	return open(path, O_RDONLY | flag);
883 }
884 
get_device_info(int i)885 int get_device_info(int i)
886 {
887 	int32_t fd = 0;
888 	uint32_t sector_size;
889 #ifndef BLKGETSIZE64
890 	uint32_t total_sectors;
891 #endif
892 	struct stat *stat_buf;
893 #ifdef HDIO_GETGIO
894 	struct hd_geometry geom;
895 #endif
896 #if !defined(WITH_ANDROID) && defined(__linux__)
897 	sg_io_hdr_t io_hdr;
898 	unsigned char reply_buffer[96] = {0};
899 	unsigned char model_inq[6] = {MODELINQUIRY};
900 #endif
901 	struct device_info *dev = c.devices + i;
902 
903 	if (c.sparse_mode) {
904 		fd = open(dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
905 		if (fd < 0) {
906 			fd = open_check_fs(dev->path, O_BINARY);
907 			if (fd < 0) {
908 				MSG(0, "\tError: Failed to open a sparse file!\n");
909 				return -1;
910 			}
911 		}
912 	}
913 
914 	stat_buf = malloc(sizeof(struct stat));
915 	ASSERT(stat_buf);
916 
917 	if (!c.sparse_mode) {
918 		if (stat(dev->path, stat_buf) < 0 ) {
919 			MSG(0, "\tError: Failed to get the device stat!\n");
920 			free(stat_buf);
921 			return -1;
922 		}
923 
924 		if (S_ISBLK(stat_buf->st_mode) &&
925 				!c.force && c.func != DUMP && !c.dry_run) {
926 			fd = open(dev->path, O_RDWR | O_EXCL);
927 			if (fd < 0)
928 				fd = open_check_fs(dev->path, O_EXCL);
929 		} else {
930 			fd = open(dev->path, O_RDWR);
931 			if (fd < 0)
932 				fd = open_check_fs(dev->path, 0);
933 		}
934 	}
935 	if (fd < 0) {
936 		MSG(0, "\tError: Failed to open the device!\n");
937 		free(stat_buf);
938 		return -1;
939 	}
940 
941 	dev->fd = fd;
942 
943 	if (c.sparse_mode) {
944 		if (f2fs_init_sparse_file()) {
945 			free(stat_buf);
946 			return -1;
947 		}
948 	}
949 
950 	if (c.kd == -1) {
951 #if !defined(WITH_ANDROID) && defined(__linux__)
952 		c.kd = open("/proc/version", O_RDONLY);
953 #endif
954 		if (c.kd < 0) {
955 			MSG(0, "Info: not exist /proc/version!\n");
956 			c.kd = -2;
957 		}
958 	}
959 
960 	if (c.sparse_mode) {
961 		dev->total_sectors = c.device_size / dev->sector_size;
962 	} else if (S_ISREG(stat_buf->st_mode)) {
963 		dev->total_sectors = stat_buf->st_size / dev->sector_size;
964 	} else if (S_ISBLK(stat_buf->st_mode)) {
965 #ifdef BLKSSZGET
966 		if (ioctl(fd, BLKSSZGET, &sector_size) < 0)
967 			MSG(0, "\tError: Using the default sector size\n");
968 		else if (dev->sector_size < sector_size)
969 			dev->sector_size = sector_size;
970 #endif
971 #ifdef BLKGETSIZE64
972 		if (ioctl(fd, BLKGETSIZE64, &dev->total_sectors) < 0) {
973 			MSG(0, "\tError: Cannot get the device size\n");
974 			free(stat_buf);
975 			return -1;
976 		}
977 #else
978 		if (ioctl(fd, BLKGETSIZE, &total_sectors) < 0) {
979 			MSG(0, "\tError: Cannot get the device size\n");
980 			free(stat_buf);
981 			return -1;
982 		}
983 		dev->total_sectors = total_sectors;
984 #endif
985 		dev->total_sectors /= dev->sector_size;
986 
987 		if (i == 0) {
988 #ifdef HDIO_GETGIO
989 			if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
990 				c.start_sector = 0;
991 			else
992 				c.start_sector = geom.start;
993 #else
994 			c.start_sector = 0;
995 #endif
996 		}
997 
998 #if !defined(WITH_ANDROID) && defined(__linux__)
999 		/* Send INQUIRY command */
1000 		memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
1001 		io_hdr.interface_id = 'S';
1002 		io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
1003 		io_hdr.dxfer_len = sizeof(reply_buffer);
1004 		io_hdr.dxferp = reply_buffer;
1005 		io_hdr.cmd_len = sizeof(model_inq);
1006 		io_hdr.cmdp = model_inq;
1007 		io_hdr.timeout = 1000;
1008 
1009 		if (!ioctl(fd, SG_IO, &io_hdr)) {
1010 			MSG(0, "Info: [%s] Disk Model: %.16s\n",
1011 					dev->path, reply_buffer+16);
1012 		}
1013 #endif
1014 	} else {
1015 		MSG(0, "\tError: Volume type is not supported!!!\n");
1016 		free(stat_buf);
1017 		return -1;
1018 	}
1019 
1020 	if (!c.sector_size) {
1021 		c.sector_size = dev->sector_size;
1022 		c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
1023 	} else if (c.sector_size != c.devices[i].sector_size) {
1024 		MSG(0, "\tError: Different sector sizes!!!\n");
1025 		free(stat_buf);
1026 		return -1;
1027 	}
1028 
1029 #if !defined(WITH_ANDROID) && defined(__linux__)
1030 	if (S_ISBLK(stat_buf->st_mode)) {
1031 		if (f2fs_get_zoned_model(i) < 0) {
1032 			free(stat_buf);
1033 			return -1;
1034 		}
1035 	}
1036 
1037 	if (dev->zoned_model != F2FS_ZONED_NONE) {
1038 
1039 		/* Get the number of blocks per zones */
1040 		if (f2fs_get_zone_blocks(i)) {
1041 			MSG(0, "\tError: Failed to get number of blocks per zone\n");
1042 			free(stat_buf);
1043 			return -1;
1044 		}
1045 
1046 		/*
1047 		 * Check zone configuration: for the first disk of a
1048 		 * multi-device volume, conventional zones are needed.
1049 		 */
1050 		if (f2fs_check_zones(i)) {
1051 			MSG(0, "\tError: Failed to check zone configuration\n");
1052 			free(stat_buf);
1053 			return -1;
1054 		}
1055 		MSG(0, "Info: Host-%s zoned block device:\n",
1056 				(dev->zoned_model == F2FS_ZONED_HA) ?
1057 					"aware" : "managed");
1058 		MSG(0, "      %u zones, %u randomly writeable zones\n",
1059 				dev->nr_zones, dev->nr_rnd_zones);
1060 		MSG(0, "      %lu blocks per zone\n",
1061 				dev->zone_blocks);
1062 	}
1063 #endif
1064 	/* adjust wanted_total_sectors */
1065 	if (c.wanted_total_sectors != -1) {
1066 		MSG(0, "Info: wanted sectors = %"PRIu64" (in %"PRIu64" bytes)\n",
1067 				c.wanted_total_sectors, c.wanted_sector_size);
1068 		if (c.wanted_sector_size == -1) {
1069 			c.wanted_sector_size = dev->sector_size;
1070 		} else if (dev->sector_size != c.wanted_sector_size) {
1071 			c.wanted_total_sectors *= c.wanted_sector_size;
1072 			c.wanted_total_sectors /= dev->sector_size;
1073 		}
1074 	}
1075 
1076 	c.total_sectors += dev->total_sectors;
1077 	free(stat_buf);
1078 	return 0;
1079 }
1080 
1081 #else
1082 
1083 #include "windows.h"
1084 #include "winioctl.h"
1085 
1086 #if (_WIN32_WINNT >= 0x0500)
1087 #define HAVE_GET_FILE_SIZE_EX 1
1088 #endif
1089 
win_get_device_size(const char * file,uint64_t * device_size)1090 static int win_get_device_size(const char *file, uint64_t *device_size)
1091 {
1092 	HANDLE dev;
1093 	PARTITION_INFORMATION pi;
1094 	DISK_GEOMETRY gi;
1095 	DWORD retbytes;
1096 #ifdef HAVE_GET_FILE_SIZE_EX
1097 	LARGE_INTEGER filesize;
1098 #else
1099 	DWORD filesize;
1100 #endif /* HAVE_GET_FILE_SIZE_EX */
1101 
1102 	dev = CreateFile(file, GENERIC_READ,
1103 			FILE_SHARE_READ | FILE_SHARE_WRITE ,
1104 			NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  NULL);
1105 
1106 	if (dev == INVALID_HANDLE_VALUE)
1107 		return EBADF;
1108 	if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
1109 				&pi, sizeof(PARTITION_INFORMATION),
1110 				&pi, sizeof(PARTITION_INFORMATION),
1111 				&retbytes, NULL)) {
1112 
1113 		*device_size = 	pi.PartitionLength.QuadPart;
1114 
1115 	} else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
1116 				&gi, sizeof(DISK_GEOMETRY),
1117 				&gi, sizeof(DISK_GEOMETRY),
1118 				&retbytes, NULL)) {
1119 
1120 		*device_size = gi.BytesPerSector *
1121 			gi.SectorsPerTrack *
1122 			gi.TracksPerCylinder *
1123 			gi.Cylinders.QuadPart;
1124 
1125 #ifdef HAVE_GET_FILE_SIZE_EX
1126 	} else if (GetFileSizeEx(dev, &filesize)) {
1127 		*device_size = filesize.QuadPart;
1128 	}
1129 #else
1130 	} else {
1131 		filesize = GetFileSize(dev, NULL);
1132 		if (INVALID_FILE_SIZE != filesize)
1133 			return -1;
1134 		*device_size = filesize;
1135 	}
1136 #endif /* HAVE_GET_FILE_SIZE_EX */
1137 
1138 	CloseHandle(dev);
1139 	return 0;
1140 }
1141 
get_device_info(int i)1142 int get_device_info(int i)
1143 {
1144 	struct device_info *dev = c.devices + i;
1145 	uint64_t device_size = 0;
1146 	int32_t fd = 0;
1147 
1148 	/* Block device target is not supported on Windows. */
1149 	if (!c.sparse_mode) {
1150 		if (win_get_device_size(dev->path, &device_size)) {
1151 			MSG(0, "\tError: Failed to get device size!\n");
1152 			return -1;
1153 		}
1154 	} else {
1155 		device_size = c.device_size;
1156 	}
1157 	if (c.sparse_mode) {
1158 		fd = open((char *)dev->path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
1159 	} else {
1160 		fd = open((char *)dev->path, O_RDWR | O_BINARY);
1161 	}
1162 	if (fd < 0) {
1163 		MSG(0, "\tError: Failed to open the device!\n");
1164 		return -1;
1165 	}
1166 	dev->fd = fd;
1167 	dev->total_sectors = device_size / dev->sector_size;
1168 	c.start_sector = 0;
1169 	c.sector_size = dev->sector_size;
1170 	c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
1171 	c.total_sectors += dev->total_sectors;
1172 
1173 	if (c.sparse_mode && f2fs_init_sparse_file())
1174 		return -1;
1175 	return 0;
1176 }
1177 #endif
1178 
f2fs_get_device_info(void)1179 int f2fs_get_device_info(void)
1180 {
1181 	int i;
1182 
1183 	for (i = 0; i < c.ndevs; i++)
1184 		if (get_device_info(i))
1185 			return -1;
1186 	return 0;
1187 }
1188 
f2fs_get_f2fs_info(void)1189 int f2fs_get_f2fs_info(void)
1190 {
1191 	int i;
1192 
1193 	if (c.wanted_total_sectors < c.total_sectors) {
1194 		MSG(0, "Info: total device sectors = %"PRIu64" (in %u bytes)\n",
1195 				c.total_sectors, c.sector_size);
1196 		c.total_sectors = c.wanted_total_sectors;
1197 		c.devices[0].total_sectors = c.total_sectors;
1198 	}
1199 	if (c.total_sectors * c.sector_size >
1200 		(u_int64_t)F2FS_MAX_SEGMENT * 2 * 1024 * 1024) {
1201 		MSG(0, "\tError: F2FS can support 16TB at most!!!\n");
1202 		return -1;
1203 	}
1204 
1205 	/*
1206 	 * Check device types and determine the final volume operation mode:
1207 	 *   - If all devices are regular block devices, default operation.
1208 	 *   - If at least one HM device is found, operate in HM mode (BLKZONED
1209 	 *     feature will be enabled by mkfs).
1210 	 *   - If an HA device is found, let mkfs decide based on the -m option
1211 	 *     setting by the user.
1212 	 */
1213 	c.zoned_model = F2FS_ZONED_NONE;
1214 	for (i = 0; i < c.ndevs; i++) {
1215 		switch (c.devices[i].zoned_model) {
1216 		case F2FS_ZONED_NONE:
1217 			continue;
1218 		case F2FS_ZONED_HM:
1219 			c.zoned_model = F2FS_ZONED_HM;
1220 			break;
1221 		case F2FS_ZONED_HA:
1222 			if (c.zoned_model != F2FS_ZONED_HM)
1223 				c.zoned_model = F2FS_ZONED_HA;
1224 			break;
1225 		}
1226 	}
1227 
1228 	if (c.zoned_model != F2FS_ZONED_NONE) {
1229 
1230 		/*
1231 		 * For zoned model, the zones sizes of all zoned devices must
1232 		 * be equal.
1233 		 */
1234 		for (i = 0; i < c.ndevs; i++) {
1235 			if (c.devices[i].zoned_model == F2FS_ZONED_NONE)
1236 				continue;
1237 			if (c.zone_blocks &&
1238 				c.zone_blocks != c.devices[i].zone_blocks) {
1239 				MSG(0, "\tError: zones of different size are "
1240 				       "not supported\n");
1241 				return -1;
1242 			}
1243 			c.zone_blocks = c.devices[i].zone_blocks;
1244 		}
1245 
1246 		/*
1247 		 * Align sections to the device zone size and align F2FS zones
1248 		 * to the device zones. For F2FS_ZONED_HA model without the
1249 		 * BLKZONED feature set at format time, this is only an
1250 		 * optimization as sequential writes will not be enforced.
1251 		 */
1252 		c.segs_per_sec = c.zone_blocks / DEFAULT_BLOCKS_PER_SEGMENT;
1253 		c.secs_per_zone = 1;
1254 	} else {
1255 		if(c.zoned_mode != 0) {
1256 			MSG(0, "\n Error: %s may not be a zoned block device \n",
1257 					c.devices[0].path);
1258 			return -1;
1259 		}
1260 	}
1261 
1262 	c.segs_per_zone = c.segs_per_sec * c.secs_per_zone;
1263 
1264 	MSG(0, "Info: Segments per section = %d\n", c.segs_per_sec);
1265 	MSG(0, "Info: Sections per zone = %d\n", c.secs_per_zone);
1266 	MSG(0, "Info: sector size = %u\n", c.sector_size);
1267 	MSG(0, "Info: total sectors = %"PRIu64" (%"PRIu64" MB)\n",
1268 				c.total_sectors, (c.total_sectors *
1269 					(c.sector_size >> 9)) >> 11);
1270 	return 0;
1271 }
1272 
calc_extra_isize(void)1273 unsigned int calc_extra_isize(void)
1274 {
1275 	unsigned int size = offsetof(struct f2fs_inode, i_projid);
1276 
1277 	if (c.feature & cpu_to_le32(F2FS_FEATURE_FLEXIBLE_INLINE_XATTR))
1278 		size = offsetof(struct f2fs_inode, i_projid);
1279 	if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA))
1280 		size = offsetof(struct f2fs_inode, i_inode_checksum);
1281 	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
1282 		size = offsetof(struct f2fs_inode, i_crtime);
1283 	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME))
1284 		size = offsetof(struct f2fs_inode, i_compr_blocks);
1285 	if (c.feature & cpu_to_le32(F2FS_FEATURE_COMPRESSION))
1286 		size = offsetof(struct f2fs_inode, i_extra_end);
1287 
1288 	return size - F2FS_EXTRA_ISIZE_OFFSET;
1289 }
1290 
1291 #define ARRAY_SIZE(array)			\
1292 	(sizeof(array) / sizeof(array[0]))
1293 
1294 static const struct {
1295 	char *name;
1296 	__u16 encoding_magic;
1297 	__u16 default_flags;
1298 
1299 } f2fs_encoding_map[] = {
1300 	{
1301 		.encoding_magic = F2FS_ENC_UTF8_12_1,
1302 		.name = "utf8",
1303 		.default_flags = 0,
1304 	},
1305 };
1306 
1307 static const struct enc_flags {
1308 	__u16 flag;
1309 	char *param;
1310 } encoding_flags[] = {
1311 	{ F2FS_ENC_STRICT_MODE_FL, "strict" },
1312 };
1313 
1314 /* Return a positive number < 0xff indicating the encoding magic number
1315  * or a negative value indicating error. */
f2fs_str2encoding(const char * string)1316 int f2fs_str2encoding(const char *string)
1317 {
1318 	int i;
1319 
1320 	for (i = 0 ; i < ARRAY_SIZE(f2fs_encoding_map); i++)
1321 		if (!strcmp(string, f2fs_encoding_map[i].name))
1322 			return f2fs_encoding_map[i].encoding_magic;
1323 
1324 	return -EINVAL;
1325 }
1326 
f2fs_encoding2str(const int encoding)1327 char *f2fs_encoding2str(const int encoding)
1328 {
1329 	int i;
1330 
1331 	for (i = 0 ; i < ARRAY_SIZE(f2fs_encoding_map); i++)
1332 		if (f2fs_encoding_map[i].encoding_magic == encoding)
1333 			return f2fs_encoding_map[i].name;
1334 
1335 	return NULL;
1336 }
1337 
f2fs_get_encoding_flags(int encoding)1338 int f2fs_get_encoding_flags(int encoding)
1339 {
1340 	int i;
1341 
1342 	for (i = 0 ; i < ARRAY_SIZE(f2fs_encoding_map); i++)
1343 		if (f2fs_encoding_map[i].encoding_magic == encoding)
1344 			return f2fs_encoding_map[encoding].default_flags;
1345 
1346 	return 0;
1347 }
1348 
f2fs_str2encoding_flags(char ** param,__u16 * flags)1349 int f2fs_str2encoding_flags(char **param, __u16 *flags)
1350 {
1351 	char *f = strtok(*param, ",");
1352 	const struct enc_flags *fl;
1353 	int i, neg = 0;
1354 
1355 	while (f) {
1356 		neg = 0;
1357 		if (!strncmp("no", f, 2)) {
1358 			neg = 1;
1359 			f += 2;
1360 		}
1361 
1362 		for (i = 0; i < ARRAY_SIZE(encoding_flags); i++) {
1363 			fl = &encoding_flags[i];
1364 			if (!strcmp(fl->param, f)) {
1365 				if (neg) {
1366 					MSG(0, "Sub %s\n", fl->param);
1367 					*flags &= ~fl->flag;
1368 				} else {
1369 					MSG(0, "Add %s\n", fl->param);
1370 					*flags |= fl->flag;
1371 				}
1372 
1373 				goto next_flag;
1374 			}
1375 		}
1376 		*param = f;
1377 		return -EINVAL;
1378 	next_flag:
1379 		f = strtok(NULL, ":");
1380 	}
1381 	return 0;
1382 }
1383