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