• 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 #ifndef _LARGEFILE64_SOURCE
10 #define _LARGEFILE64_SOURCE
11 #endif
12 #define _FILE_OFFSET_BITS 64
13 
14 #include <f2fs_fs.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <libgen.h>
22 #ifdef HAVE_MNTENT_H
23 #include <mntent.h>
24 #endif
25 #include <time.h>
26 #include <sys/stat.h>
27 #ifdef HAVE_SYS_MOUNT_H
28 #include <sys/mount.h>
29 #endif
30 #ifdef HAVE_SYS_IOCTL_H
31 #include <sys/ioctl.h>
32 #endif
33 #ifdef HAVE_SYS_SYSMACROS_H
34 #include <sys/sysmacros.h>
35 #endif
36 #ifdef HAVE_SYS_UTSNAME_H
37 #include <sys/utsname.h>
38 #endif
39 #ifdef HAVE_SCSI_SG_H
40 #include <scsi/sg.h>
41 #endif
42 #ifdef HAVE_LINUX_HDREG_H
43 #include <linux/hdreg.h>
44 #endif
45 #ifdef HAVE_LINUX_LIMITS_H
46 #include <linux/limits.h>
47 #endif
48 
49 /* SCSI command for standard inquiry*/
50 #define MODELINQUIRY	0x12,0x00,0x00,0x00,0x4A,0x00
51 
52 #ifndef _WIN32 /* 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(uint16_t * output,wchar_t wc,size_t outsize)107 static uint16_t *wchar_to_utf16(uint16_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(uint16_t * output,const char * input,size_t outsize,size_t insize)123 int utf8_to_utf16(uint16_t *output, const char *input, size_t outsize,
124 		size_t insize)
125 {
126 	const char *inp = input;
127 	uint16_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 uint16_t * input,wchar_t * wc,size_t insize)146 static const uint16_t *utf16_to_wchar(const uint16_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 uint16_t * input,size_t outsize,size_t insize)209 int utf16_to_utf8(char *output, const uint16_t *input, size_t outsize,
210 		size_t insize)
211 {
212 	const uint16_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(uint32_t num)232 int log_base_2(uint32_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(uint32_t crc,void * buf,int len)533 uint32_t f2fs_cal_crc32(uint32_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(uint32_t blk_crc,void * buf,int len)545 int f2fs_crc_valid(uint32_t blk_crc, void *buf, int len)
546 {
547 	uint32_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(_WIN32) || 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 _WIN32
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 _WIN32
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 
is_power_of_2(unsigned long n)885 static int is_power_of_2(unsigned long n)
886 {
887 	return (n != 0 && ((n & (n - 1)) == 0));
888 }
889 
get_device_info(int i)890 int get_device_info(int i)
891 {
892 	int32_t fd = 0;
893 	uint32_t sector_size;
894 #ifndef BLKGETSIZE64
895 	uint32_t total_sectors;
896 #endif
897 	struct stat *stat_buf;
898 #ifdef HDIO_GETGIO
899 	struct hd_geometry geom;
900 #endif
901 #ifdef __linux__
902 	sg_io_hdr_t io_hdr;
903 	unsigned char reply_buffer[96] = {0};
904 	unsigned char model_inq[6] = {MODELINQUIRY};
905 #endif
906 	struct device_info *dev = c.devices + i;
907 
908 	if (c.sparse_mode) {
909 		fd = open(dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
910 		if (fd < 0) {
911 			fd = open_check_fs(dev->path, O_BINARY);
912 			if (fd < 0) {
913 				MSG(0, "\tError: Failed to open a sparse file!\n");
914 				return -1;
915 			}
916 		}
917 	}
918 
919 	stat_buf = malloc(sizeof(struct stat));
920 	ASSERT(stat_buf);
921 
922 	if (!c.sparse_mode) {
923 		if (stat(dev->path, stat_buf) < 0 ) {
924 			MSG(0, "\tError: Failed to get the device stat!\n");
925 			free(stat_buf);
926 			return -1;
927 		}
928 
929 		if (S_ISBLK(stat_buf->st_mode) &&
930 				!c.force && c.func != DUMP && !c.dry_run) {
931 			fd = open(dev->path, O_RDWR | O_EXCL);
932 			if (fd < 0)
933 				fd = open_check_fs(dev->path, O_EXCL);
934 		} else {
935 			fd = open(dev->path, O_RDWR);
936 			if (fd < 0)
937 				fd = open_check_fs(dev->path, 0);
938 		}
939 	}
940 	if (fd < 0) {
941 		MSG(0, "\tError: Failed to open the device!\n");
942 		free(stat_buf);
943 		return -1;
944 	}
945 
946 	dev->fd = fd;
947 
948 	if (c.sparse_mode) {
949 		if (f2fs_init_sparse_file()) {
950 			free(stat_buf);
951 			return -1;
952 		}
953 	}
954 
955 	if (c.kd == -1) {
956 #if !defined(WITH_ANDROID) && defined(__linux__)
957 		c.kd = open("/proc/version", O_RDONLY);
958 #endif
959 		if (c.kd < 0) {
960 			MSG(0, "Info: not exist /proc/version!\n");
961 			c.kd = -2;
962 		}
963 	}
964 
965 	if (c.sparse_mode) {
966 		dev->total_sectors = c.device_size / dev->sector_size;
967 	} else if (S_ISREG(stat_buf->st_mode)) {
968 		dev->total_sectors = stat_buf->st_size / dev->sector_size;
969 	} else if (S_ISBLK(stat_buf->st_mode)) {
970 #ifdef BLKSSZGET
971 		if (ioctl(fd, BLKSSZGET, &sector_size) < 0)
972 			MSG(0, "\tError: Using the default sector size\n");
973 		else if (dev->sector_size < sector_size)
974 			dev->sector_size = sector_size;
975 #endif
976 #ifdef BLKGETSIZE64
977 		if (ioctl(fd, BLKGETSIZE64, &dev->total_sectors) < 0) {
978 			MSG(0, "\tError: Cannot get the device size\n");
979 			free(stat_buf);
980 			return -1;
981 		}
982 #else
983 		if (ioctl(fd, BLKGETSIZE, &total_sectors) < 0) {
984 			MSG(0, "\tError: Cannot get the device size\n");
985 			free(stat_buf);
986 			return -1;
987 		}
988 		dev->total_sectors = total_sectors;
989 #endif
990 		dev->total_sectors /= dev->sector_size;
991 
992 		if (i == 0) {
993 #ifdef HDIO_GETGIO
994 			if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
995 				c.start_sector = 0;
996 			else
997 				c.start_sector = geom.start;
998 #else
999 			c.start_sector = 0;
1000 #endif
1001 		}
1002 
1003 #ifdef __linux__
1004 		/* Send INQUIRY command */
1005 		memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
1006 		io_hdr.interface_id = 'S';
1007 		io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
1008 		io_hdr.dxfer_len = sizeof(reply_buffer);
1009 		io_hdr.dxferp = reply_buffer;
1010 		io_hdr.cmd_len = sizeof(model_inq);
1011 		io_hdr.cmdp = model_inq;
1012 		io_hdr.timeout = 1000;
1013 
1014 		if (!ioctl(fd, SG_IO, &io_hdr)) {
1015 			MSG(0, "Info: [%s] Disk Model: %.16s\n",
1016 					dev->path, reply_buffer+16);
1017 		}
1018 #endif
1019 	} else {
1020 		MSG(0, "\tError: Volume type is not supported!!!\n");
1021 		free(stat_buf);
1022 		return -1;
1023 	}
1024 
1025 	if (!c.sector_size) {
1026 		c.sector_size = dev->sector_size;
1027 		c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
1028 	} else if (c.sector_size != c.devices[i].sector_size) {
1029 		MSG(0, "\tError: Different sector sizes!!!\n");
1030 		free(stat_buf);
1031 		return -1;
1032 	}
1033 
1034 #ifdef __linux__
1035 	if (S_ISBLK(stat_buf->st_mode)) {
1036 		if (f2fs_get_zoned_model(i) < 0) {
1037 			free(stat_buf);
1038 			return -1;
1039 		}
1040 	}
1041 
1042 	if (dev->zoned_model != F2FS_ZONED_NONE) {
1043 
1044 		/* Get the number of blocks per zones */
1045 		if (f2fs_get_zone_blocks(i)) {
1046 			MSG(0, "\tError: Failed to get number of blocks per zone\n");
1047 			free(stat_buf);
1048 			return -1;
1049 		}
1050 
1051 		if (!is_power_of_2(dev->zone_size)) {
1052 			MSG(0, "\tError: zoned: illegal zone size %lu (not a power of 2)\n",
1053 					dev->zone_size);
1054 			free(stat_buf);
1055 			return -1;
1056 		}
1057 
1058 		/*
1059 		 * Check zone configuration: for the first disk of a
1060 		 * multi-device volume, conventional zones are needed.
1061 		 */
1062 		if (f2fs_check_zones(i)) {
1063 			MSG(0, "\tError: Failed to check zone configuration\n");
1064 			free(stat_buf);
1065 			return -1;
1066 		}
1067 		MSG(0, "Info: Host-%s zoned block device:\n",
1068 				(dev->zoned_model == F2FS_ZONED_HA) ?
1069 					"aware" : "managed");
1070 		MSG(0, "      %u zones, %lu zone size(bytes), %u randomly writeable zones\n",
1071 				dev->nr_zones, dev->zone_size,
1072 				dev->nr_rnd_zones);
1073 		MSG(0, "      %lu blocks per zone\n",
1074 				dev->zone_blocks);
1075 	}
1076 #endif
1077 	/* adjust wanted_total_sectors */
1078 	if (c.wanted_total_sectors != -1) {
1079 		MSG(0, "Info: wanted sectors = %"PRIu64" (in %"PRIu64" bytes)\n",
1080 				c.wanted_total_sectors, c.wanted_sector_size);
1081 		if (c.wanted_sector_size == -1) {
1082 			c.wanted_sector_size = dev->sector_size;
1083 		} else if (dev->sector_size != c.wanted_sector_size) {
1084 			c.wanted_total_sectors *= c.wanted_sector_size;
1085 			c.wanted_total_sectors /= dev->sector_size;
1086 		}
1087 	}
1088 
1089 	c.total_sectors += dev->total_sectors;
1090 	free(stat_buf);
1091 	return 0;
1092 }
1093 
1094 #else
1095 
1096 #include "windows.h"
1097 #include "winioctl.h"
1098 
1099 #if (_WIN32_WINNT >= 0x0500)
1100 #define HAVE_GET_FILE_SIZE_EX 1
1101 #endif
1102 
win_get_device_size(const char * file,uint64_t * device_size)1103 static int win_get_device_size(const char *file, uint64_t *device_size)
1104 {
1105 	HANDLE dev;
1106 	PARTITION_INFORMATION pi;
1107 	DISK_GEOMETRY gi;
1108 	DWORD retbytes;
1109 #ifdef HAVE_GET_FILE_SIZE_EX
1110 	LARGE_INTEGER filesize;
1111 #else
1112 	DWORD filesize;
1113 #endif /* HAVE_GET_FILE_SIZE_EX */
1114 
1115 	dev = CreateFile(file, GENERIC_READ,
1116 			FILE_SHARE_READ | FILE_SHARE_WRITE ,
1117 			NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  NULL);
1118 
1119 	if (dev == INVALID_HANDLE_VALUE)
1120 		return EBADF;
1121 	if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
1122 				&pi, sizeof(PARTITION_INFORMATION),
1123 				&pi, sizeof(PARTITION_INFORMATION),
1124 				&retbytes, NULL)) {
1125 
1126 		*device_size = 	pi.PartitionLength.QuadPart;
1127 
1128 	} else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
1129 				&gi, sizeof(DISK_GEOMETRY),
1130 				&gi, sizeof(DISK_GEOMETRY),
1131 				&retbytes, NULL)) {
1132 
1133 		*device_size = gi.BytesPerSector *
1134 			gi.SectorsPerTrack *
1135 			gi.TracksPerCylinder *
1136 			gi.Cylinders.QuadPart;
1137 
1138 #ifdef HAVE_GET_FILE_SIZE_EX
1139 	} else if (GetFileSizeEx(dev, &filesize)) {
1140 		*device_size = filesize.QuadPart;
1141 	}
1142 #else
1143 	} else {
1144 		filesize = GetFileSize(dev, NULL);
1145 		if (INVALID_FILE_SIZE != filesize)
1146 			return -1;
1147 		*device_size = filesize;
1148 	}
1149 #endif /* HAVE_GET_FILE_SIZE_EX */
1150 
1151 	CloseHandle(dev);
1152 	return 0;
1153 }
1154 
get_device_info(int i)1155 int get_device_info(int i)
1156 {
1157 	struct device_info *dev = c.devices + i;
1158 	uint64_t device_size = 0;
1159 	int32_t fd = 0;
1160 
1161 	/* Block device target is not supported on Windows. */
1162 	if (!c.sparse_mode) {
1163 		if (win_get_device_size(dev->path, &device_size)) {
1164 			MSG(0, "\tError: Failed to get device size!\n");
1165 			return -1;
1166 		}
1167 	} else {
1168 		device_size = c.device_size;
1169 	}
1170 	if (c.sparse_mode) {
1171 		fd = open((char *)dev->path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
1172 	} else {
1173 		fd = open((char *)dev->path, O_RDWR | O_BINARY);
1174 	}
1175 	if (fd < 0) {
1176 		MSG(0, "\tError: Failed to open the device!\n");
1177 		return -1;
1178 	}
1179 	dev->fd = fd;
1180 	dev->total_sectors = device_size / dev->sector_size;
1181 	c.start_sector = 0;
1182 	c.sector_size = dev->sector_size;
1183 	c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
1184 	c.total_sectors += dev->total_sectors;
1185 
1186 	if (c.sparse_mode && f2fs_init_sparse_file())
1187 		return -1;
1188 	return 0;
1189 }
1190 #endif
1191 
f2fs_get_device_info(void)1192 int f2fs_get_device_info(void)
1193 {
1194 	int i;
1195 
1196 	for (i = 0; i < c.ndevs; i++)
1197 		if (get_device_info(i))
1198 			return -1;
1199 	return 0;
1200 }
1201 
f2fs_get_f2fs_info(void)1202 int f2fs_get_f2fs_info(void)
1203 {
1204 	int i;
1205 
1206 	if (c.wanted_total_sectors < c.total_sectors) {
1207 		MSG(0, "Info: total device sectors = %"PRIu64" (in %u bytes)\n",
1208 				c.total_sectors, c.sector_size);
1209 		c.total_sectors = c.wanted_total_sectors;
1210 		c.devices[0].total_sectors = c.total_sectors;
1211 	}
1212 	if (c.total_sectors * c.sector_size >
1213 		(uint64_t)F2FS_MAX_SEGMENT * 2 * 1024 * 1024) {
1214 		MSG(0, "\tError: F2FS can support 16TB at most!!!\n");
1215 		return -1;
1216 	}
1217 
1218 	/*
1219 	 * Check device types and determine the final volume operation mode:
1220 	 *   - If all devices are regular block devices, default operation.
1221 	 *   - If at least one HM device is found, operate in HM mode (BLKZONED
1222 	 *     feature will be enabled by mkfs).
1223 	 *   - If an HA device is found, let mkfs decide based on the -m option
1224 	 *     setting by the user.
1225 	 */
1226 	c.zoned_model = F2FS_ZONED_NONE;
1227 	for (i = 0; i < c.ndevs; i++) {
1228 		switch (c.devices[i].zoned_model) {
1229 		case F2FS_ZONED_NONE:
1230 			continue;
1231 		case F2FS_ZONED_HM:
1232 			c.zoned_model = F2FS_ZONED_HM;
1233 			break;
1234 		case F2FS_ZONED_HA:
1235 			if (c.zoned_model != F2FS_ZONED_HM)
1236 				c.zoned_model = F2FS_ZONED_HA;
1237 			break;
1238 		}
1239 	}
1240 
1241 	if (c.zoned_model != F2FS_ZONED_NONE) {
1242 
1243 		/*
1244 		 * For zoned model, the zones sizes of all zoned devices must
1245 		 * be equal.
1246 		 */
1247 		for (i = 0; i < c.ndevs; i++) {
1248 			if (c.devices[i].zoned_model == F2FS_ZONED_NONE)
1249 				continue;
1250 			if (c.zone_blocks &&
1251 				c.zone_blocks != c.devices[i].zone_blocks) {
1252 				MSG(0, "\tError: zones of different size are "
1253 				       "not supported\n");
1254 				return -1;
1255 			}
1256 			c.zone_blocks = c.devices[i].zone_blocks;
1257 		}
1258 
1259 		/*
1260 		 * Align sections to the device zone size and align F2FS zones
1261 		 * to the device zones. For F2FS_ZONED_HA model without the
1262 		 * BLKZONED feature set at format time, this is only an
1263 		 * optimization as sequential writes will not be enforced.
1264 		 */
1265 		c.segs_per_sec = c.zone_blocks / DEFAULT_BLOCKS_PER_SEGMENT;
1266 		c.secs_per_zone = 1;
1267 	} else {
1268 		if(c.zoned_mode != 0) {
1269 			MSG(0, "\n Error: %s may not be a zoned block device \n",
1270 					c.devices[0].path);
1271 			return -1;
1272 		}
1273 	}
1274 
1275 	c.segs_per_zone = c.segs_per_sec * c.secs_per_zone;
1276 
1277 	if (c.func != MKFS)
1278 		return 0;
1279 
1280 	MSG(0, "Info: Segments per section = %d\n", c.segs_per_sec);
1281 	MSG(0, "Info: Sections per zone = %d\n", c.secs_per_zone);
1282 	MSG(0, "Info: sector size = %u\n", c.sector_size);
1283 	MSG(0, "Info: total sectors = %"PRIu64" (%"PRIu64" MB)\n",
1284 				c.total_sectors, (c.total_sectors *
1285 					(c.sector_size >> 9)) >> 11);
1286 	return 0;
1287 }
1288 
calc_extra_isize(void)1289 unsigned int calc_extra_isize(void)
1290 {
1291 	unsigned int size = offsetof(struct f2fs_inode, i_projid);
1292 
1293 	if (c.feature & cpu_to_le32(F2FS_FEATURE_FLEXIBLE_INLINE_XATTR))
1294 		size = offsetof(struct f2fs_inode, i_projid);
1295 	if (c.feature & cpu_to_le32(F2FS_FEATURE_PRJQUOTA))
1296 		size = offsetof(struct f2fs_inode, i_inode_checksum);
1297 	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
1298 		size = offsetof(struct f2fs_inode, i_crtime);
1299 	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CRTIME))
1300 		size = offsetof(struct f2fs_inode, i_compr_blocks);
1301 	if (c.feature & cpu_to_le32(F2FS_FEATURE_COMPRESSION))
1302 		size = offsetof(struct f2fs_inode, i_extra_end);
1303 
1304 	return size - F2FS_EXTRA_ISIZE_OFFSET;
1305 }
1306 
1307 #define ARRAY_SIZE(array)			\
1308 	(sizeof(array) / sizeof(array[0]))
1309 
1310 static const struct {
1311 	char *name;
1312 	__u16 encoding_magic;
1313 	__u16 default_flags;
1314 
1315 } f2fs_encoding_map[] = {
1316 	{
1317 		.encoding_magic = F2FS_ENC_UTF8_12_1,
1318 		.name = "utf8",
1319 		.default_flags = 0,
1320 	},
1321 };
1322 
1323 static const struct enc_flags {
1324 	__u16 flag;
1325 	char *param;
1326 } encoding_flags[] = {
1327 	{ F2FS_ENC_STRICT_MODE_FL, "strict" },
1328 };
1329 
1330 /* Return a positive number < 0xff indicating the encoding magic number
1331  * or a negative value indicating error. */
f2fs_str2encoding(const char * string)1332 int f2fs_str2encoding(const char *string)
1333 {
1334 	int i;
1335 
1336 	for (i = 0 ; i < ARRAY_SIZE(f2fs_encoding_map); i++)
1337 		if (!strcmp(string, f2fs_encoding_map[i].name))
1338 			return f2fs_encoding_map[i].encoding_magic;
1339 
1340 	return -EINVAL;
1341 }
1342 
f2fs_encoding2str(const int encoding)1343 char *f2fs_encoding2str(const int encoding)
1344 {
1345 	int i;
1346 
1347 	for (i = 0 ; i < ARRAY_SIZE(f2fs_encoding_map); i++)
1348 		if (f2fs_encoding_map[i].encoding_magic == encoding)
1349 			return f2fs_encoding_map[i].name;
1350 
1351 	return NULL;
1352 }
1353 
f2fs_get_encoding_flags(int encoding)1354 int f2fs_get_encoding_flags(int encoding)
1355 {
1356 	int i;
1357 
1358 	for (i = 0 ; i < ARRAY_SIZE(f2fs_encoding_map); i++)
1359 		if (f2fs_encoding_map[i].encoding_magic == encoding)
1360 			return f2fs_encoding_map[encoding].default_flags;
1361 
1362 	return 0;
1363 }
1364 
f2fs_str2encoding_flags(char ** param,__u16 * flags)1365 int f2fs_str2encoding_flags(char **param, __u16 *flags)
1366 {
1367 	char *f = strtok(*param, ",");
1368 	const struct enc_flags *fl;
1369 	int i, neg = 0;
1370 
1371 	while (f) {
1372 		neg = 0;
1373 		if (!strncmp("no", f, 2)) {
1374 			neg = 1;
1375 			f += 2;
1376 		}
1377 
1378 		for (i = 0; i < ARRAY_SIZE(encoding_flags); i++) {
1379 			fl = &encoding_flags[i];
1380 			if (!strcmp(fl->param, f)) {
1381 				if (neg) {
1382 					MSG(0, "Sub %s\n", fl->param);
1383 					*flags &= ~fl->flag;
1384 				} else {
1385 					MSG(0, "Add %s\n", fl->param);
1386 					*flags |= fl->flag;
1387 				}
1388 
1389 				goto next_flag;
1390 			}
1391 		}
1392 		*param = f;
1393 		return -EINVAL;
1394 	next_flag:
1395 		f = strtok(NULL, ":");
1396 	}
1397 	return 0;
1398 }
1399