• 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 #ifdef HAVE_MNTENT_H
20 #include <mntent.h>
21 #endif
22 #include <time.h>
23 #include <sys/stat.h>
24 #ifndef ANDROID_WINDOWS_HOST
25 #include <sys/mount.h>
26 #include <sys/ioctl.h>
27 #endif
28 #ifdef HAVE_SYS_SYSMACROS_H
29 #include <sys/sysmacros.h>
30 #endif
31 #ifdef HAVE_SYS_UTSNAME_H
32 #include <sys/utsname.h>
33 #endif
34 #ifndef WITH_ANDROID
35 #ifdef HAVE_SCSI_SG_H
36 #include <scsi/sg.h>
37 #endif
38 #endif
39 #ifdef HAVE_LINUX_HDREG_H
40 #include <linux/hdreg.h>
41 #endif
42 #ifdef HAVE_LINUX_LIMITS_H
43 #include <linux/limits.h>
44 #endif
45 
46 #ifndef WITH_ANDROID
47 /* SCSI command for standard inquiry*/
48 #define MODELINQUIRY	0x12,0x00,0x00,0x00,0x4A,0x00
49 #endif
50 
51 #ifndef ANDROID_WINDOWS_HOST /* O_BINARY is windows-specific flag */
52 #define O_BINARY 0
53 #else
54 /* On Windows, wchar_t is 8 bit sized and it causes compilation errors. */
55 #define wchar_t	int
56 #endif
57 
58 /*
59  * UTF conversion codes are Copied from exfat tools.
60  */
utf8_to_wchar(const char * input,wchar_t * wc,size_t insize)61 static const char *utf8_to_wchar(const char *input, wchar_t *wc,
62 		size_t insize)
63 {
64 	if ((input[0] & 0x80) == 0 && insize >= 1) {
65 		*wc = (wchar_t) input[0];
66 		return input + 1;
67 	}
68 	if ((input[0] & 0xe0) == 0xc0 && insize >= 2) {
69 		*wc = (((wchar_t) input[0] & 0x1f) << 6) |
70 		       ((wchar_t) input[1] & 0x3f);
71 		return input + 2;
72 	}
73 	if ((input[0] & 0xf0) == 0xe0 && insize >= 3) {
74 		*wc = (((wchar_t) input[0] & 0x0f) << 12) |
75 		      (((wchar_t) input[1] & 0x3f) << 6) |
76 		       ((wchar_t) input[2] & 0x3f);
77 		return input + 3;
78 	}
79 	if ((input[0] & 0xf8) == 0xf0 && insize >= 4) {
80 		*wc = (((wchar_t) input[0] & 0x07) << 18) |
81 		      (((wchar_t) input[1] & 0x3f) << 12) |
82 		      (((wchar_t) input[2] & 0x3f) << 6) |
83 		       ((wchar_t) input[3] & 0x3f);
84 		return input + 4;
85 	}
86 	if ((input[0] & 0xfc) == 0xf8 && insize >= 5) {
87 		*wc = (((wchar_t) input[0] & 0x03) << 24) |
88 		      (((wchar_t) input[1] & 0x3f) << 18) |
89 		      (((wchar_t) input[2] & 0x3f) << 12) |
90 		      (((wchar_t) input[3] & 0x3f) << 6) |
91 		       ((wchar_t) input[4] & 0x3f);
92 		return input + 5;
93 	}
94 	if ((input[0] & 0xfe) == 0xfc && insize >= 6) {
95 		*wc = (((wchar_t) input[0] & 0x01) << 30) |
96 		      (((wchar_t) input[1] & 0x3f) << 24) |
97 		      (((wchar_t) input[2] & 0x3f) << 18) |
98 		      (((wchar_t) input[3] & 0x3f) << 12) |
99 		      (((wchar_t) input[4] & 0x3f) << 6) |
100 		       ((wchar_t) input[5] & 0x3f);
101 		return input + 6;
102 	}
103 	return NULL;
104 }
105 
wchar_to_utf16(u_int16_t * output,wchar_t wc,size_t outsize)106 static u_int16_t *wchar_to_utf16(u_int16_t *output, wchar_t wc, size_t outsize)
107 {
108 	if (wc <= 0xffff) {
109 		if (outsize == 0)
110 			return NULL;
111 		output[0] = cpu_to_le16(wc);
112 		return output + 1;
113 	}
114 	if (outsize < 2)
115 		return NULL;
116 	wc -= 0x10000;
117 	output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff));
118 	output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff));
119 	return output + 2;
120 }
121 
utf8_to_utf16(u_int16_t * output,const char * input,size_t outsize,size_t insize)122 int utf8_to_utf16(u_int16_t *output, const char *input, size_t outsize,
123 		size_t insize)
124 {
125 	const char *inp = input;
126 	u_int16_t *outp = output;
127 	wchar_t wc;
128 
129 	while ((size_t)(inp - input) < insize && *inp) {
130 		inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
131 		if (inp == NULL) {
132 			DBG(0, "illegal UTF-8 sequence\n");
133 			return -EILSEQ;
134 		}
135 		outp = wchar_to_utf16(outp, wc, outsize - (outp - output));
136 		if (outp == NULL) {
137 			DBG(0, "name is too long\n");
138 			return -ENAMETOOLONG;
139 		}
140 	}
141 	*outp = cpu_to_le16(0);
142 	return 0;
143 }
144 
utf16_to_wchar(const u_int16_t * input,wchar_t * wc,size_t insize)145 static const u_int16_t *utf16_to_wchar(const u_int16_t *input, wchar_t *wc,
146 		size_t insize)
147 {
148 	if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) {
149 		if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00)
150 			return NULL;
151 		*wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10);
152 		*wc |= (le16_to_cpu(input[1]) & 0x3ff);
153 		*wc += 0x10000;
154 		return input + 2;
155 	} else {
156 		*wc = le16_to_cpu(*input);
157 		return input + 1;
158 	}
159 }
160 
wchar_to_utf8(char * output,wchar_t wc,size_t outsize)161 static char *wchar_to_utf8(char *output, wchar_t wc, size_t outsize)
162 {
163 	if (wc <= 0x7f) {
164 		if (outsize < 1)
165 			return NULL;
166 		*output++ = (char) wc;
167 	} else if (wc <= 0x7ff) {
168 		if (outsize < 2)
169 			return NULL;
170 		*output++ = 0xc0 | (wc >> 6);
171 		*output++ = 0x80 | (wc & 0x3f);
172 	} else if (wc <= 0xffff) {
173 		if (outsize < 3)
174 			return NULL;
175 		*output++ = 0xe0 | (wc >> 12);
176 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
177 		*output++ = 0x80 | (wc & 0x3f);
178 	} else if (wc <= 0x1fffff) {
179 		if (outsize < 4)
180 			return NULL;
181 		*output++ = 0xf0 | (wc >> 18);
182 		*output++ = 0x80 | ((wc >> 12) & 0x3f);
183 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
184 		*output++ = 0x80 | (wc & 0x3f);
185 	} else if (wc <= 0x3ffffff) {
186 		if (outsize < 5)
187 			return NULL;
188 		*output++ = 0xf8 | (wc >> 24);
189 		*output++ = 0x80 | ((wc >> 18) & 0x3f);
190 		*output++ = 0x80 | ((wc >> 12) & 0x3f);
191 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
192 		*output++ = 0x80 | (wc & 0x3f);
193 	} else if (wc <= 0x7fffffff) {
194 		if (outsize < 6)
195 			return NULL;
196 		*output++ = 0xfc | (wc >> 30);
197 		*output++ = 0x80 | ((wc >> 24) & 0x3f);
198 		*output++ = 0x80 | ((wc >> 18) & 0x3f);
199 		*output++ = 0x80 | ((wc >> 12) & 0x3f);
200 		*output++ = 0x80 | ((wc >> 6) & 0x3f);
201 		*output++ = 0x80 | (wc & 0x3f);
202 	} else
203 		return NULL;
204 
205 	return output;
206 }
207 
utf16_to_utf8(char * output,const u_int16_t * input,size_t outsize,size_t insize)208 int utf16_to_utf8(char *output, const u_int16_t *input, size_t outsize,
209 		size_t insize)
210 {
211 	const u_int16_t *inp = input;
212 	char *outp = output;
213 	wchar_t wc;
214 
215 	while ((size_t)(inp - input) < insize && le16_to_cpu(*inp)) {
216 		inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
217 		if (inp == NULL) {
218 			DBG(0, "illegal UTF-16 sequence\n");
219 			return -EILSEQ;
220 		}
221 		outp = wchar_to_utf8(outp, wc, outsize - (outp - output));
222 		if (outp == NULL) {
223 			DBG(0, "name is too long\n");
224 			return -ENAMETOOLONG;
225 		}
226 	}
227 	*outp = '\0';
228 	return 0;
229 }
230 
log_base_2(u_int32_t num)231 int log_base_2(u_int32_t num)
232 {
233 	int ret = 0;
234 	if (num <= 0 || (num & (num - 1)) != 0)
235 		return -1;
236 
237 	while (num >>= 1)
238 		ret++;
239 	return ret;
240 }
241 
242 /*
243  * f2fs bit operations
244  */
245 static const int bits_in_byte[256] = {
246 	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
247 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
248 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
249 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
250 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
251 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
252 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
253 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
254 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
255 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
256 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
257 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
258 	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
259 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
260 	3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
261 	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
262 };
263 
get_bits_in_byte(unsigned char n)264 int get_bits_in_byte(unsigned char n)
265 {
266 	return bits_in_byte[n];
267 }
268 
test_and_set_bit_le(u32 nr,u8 * addr)269 int test_and_set_bit_le(u32 nr, u8 *addr)
270 {
271 	int mask, retval;
272 
273 	addr += nr >> 3;
274 	mask = 1 << ((nr & 0x07));
275 	retval = mask & *addr;
276 	*addr |= mask;
277 	return retval;
278 }
279 
test_and_clear_bit_le(u32 nr,u8 * addr)280 int test_and_clear_bit_le(u32 nr, u8 *addr)
281 {
282 	int mask, retval;
283 
284 	addr += nr >> 3;
285 	mask = 1 << ((nr & 0x07));
286 	retval = mask & *addr;
287 	*addr &= ~mask;
288 	return retval;
289 }
290 
test_bit_le(u32 nr,const u8 * addr)291 int test_bit_le(u32 nr, const u8 *addr)
292 {
293 	return ((1 << (nr & 7)) & (addr[nr >> 3]));
294 }
295 
f2fs_test_bit(unsigned int nr,const char * p)296 int f2fs_test_bit(unsigned int nr, const char *p)
297 {
298 	int mask;
299 	char *addr = (char *)p;
300 
301 	addr += (nr >> 3);
302 	mask = 1 << (7 - (nr & 0x07));
303 	return (mask & *addr) != 0;
304 }
305 
f2fs_set_bit(unsigned int nr,char * addr)306 int f2fs_set_bit(unsigned int nr, char *addr)
307 {
308 	int mask;
309 	int ret;
310 
311 	addr += (nr >> 3);
312 	mask = 1 << (7 - (nr & 0x07));
313 	ret = mask & *addr;
314 	*addr |= mask;
315 	return ret;
316 }
317 
f2fs_clear_bit(unsigned int nr,char * addr)318 int f2fs_clear_bit(unsigned int nr, char *addr)
319 {
320 	int mask;
321 	int ret;
322 
323 	addr += (nr >> 3);
324 	mask = 1 << (7 - (nr & 0x07));
325 	ret = mask & *addr;
326 	*addr &= ~mask;
327 	return ret;
328 }
329 
__ffs(u8 word)330 static inline u64 __ffs(u8 word)
331 {
332 	int num = 0;
333 
334 	if ((word & 0xf) == 0) {
335 		num += 4;
336 		word >>= 4;
337 	}
338 	if ((word & 0x3) == 0) {
339 		num += 2;
340 		word >>= 2;
341 	}
342 	if ((word & 0x1) == 0)
343 		num += 1;
344 	return num;
345 }
346 
347 /* Copied from linux/lib/find_bit.c */
348 #define BITMAP_FIRST_BYTE_MASK(start) (0xff << ((start) & (BITS_PER_BYTE - 1)))
349 
_find_next_bit_le(const u8 * addr,u64 nbits,u64 start,char invert)350 static u64 _find_next_bit_le(const u8 *addr, u64 nbits, u64 start, char invert)
351 {
352 	u8 tmp;
353 
354 	if (!nbits || start >= nbits)
355 		return nbits;
356 
357 	tmp = addr[start / BITS_PER_BYTE] ^ invert;
358 
359 	/* Handle 1st word. */
360 	tmp &= BITMAP_FIRST_BYTE_MASK(start);
361 	start = round_down(start, BITS_PER_BYTE);
362 
363 	while (!tmp) {
364 		start += BITS_PER_BYTE;
365 		if (start >= nbits)
366 			return nbits;
367 
368 		tmp = addr[start / BITS_PER_BYTE] ^ invert;
369 	}
370 
371 	return min(start + __ffs(tmp), nbits);
372 }
373 
find_next_bit_le(const u8 * addr,u64 size,u64 offset)374 u64 find_next_bit_le(const u8 *addr, u64 size, u64 offset)
375 {
376 	return _find_next_bit_le(addr, size, offset, 0);
377 }
378 
379 
find_next_zero_bit_le(const u8 * addr,u64 size,u64 offset)380 u64 find_next_zero_bit_le(const u8 *addr, u64 size, u64 offset)
381 {
382 	return _find_next_bit_le(addr, size, offset, 0xff);
383 }
384 
385 /*
386  * Hashing code adapted from ext3
387  */
388 #define DELTA 0x9E3779B9
389 
TEA_transform(unsigned int buf[4],unsigned int const in[])390 static void TEA_transform(unsigned int buf[4], unsigned int const in[])
391 {
392 	__u32 sum = 0;
393 	__u32 b0 = buf[0], b1 = buf[1];
394 	__u32 a = in[0], b = in[1], c = in[2], d = in[3];
395 	int     n = 16;
396 
397 	do {
398 		sum += DELTA;
399 		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
400 		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
401 	} while (--n);
402 
403 	buf[0] += b0;
404 	buf[1] += b1;
405 
406 }
407 
str2hashbuf(const unsigned char * msg,int len,unsigned int * buf,int num)408 static void str2hashbuf(const unsigned char *msg, int len,
409 					unsigned int *buf, int num)
410 {
411 	unsigned pad, val;
412 	int i;
413 
414 	pad = (__u32)len | ((__u32)len << 8);
415 	pad |= pad << 16;
416 
417 	val = pad;
418 	if (len > num * 4)
419 		len = num * 4;
420 	for (i = 0; i < len; i++) {
421 		if ((i % 4) == 0)
422 			val = pad;
423 		val = msg[i] + (val << 8);
424 		if ((i % 4) == 3) {
425 			*buf++ = val;
426 			val = pad;
427 			num--;
428 		}
429 	}
430 	if (--num >= 0)
431 		*buf++ = val;
432 	while (--num >= 0)
433 		*buf++ = pad;
434 
435 }
436 
437 /**
438  * Return hash value of directory entry
439  * @param name          dentry name
440  * @param len           name lenth
441  * @return              return on success hash value, errno on failure
442  */
f2fs_dentry_hash(const unsigned char * name,int len)443 f2fs_hash_t f2fs_dentry_hash(const unsigned char *name, int len)
444 {
445 	__u32 hash;
446 	f2fs_hash_t	f2fs_hash;
447 	const unsigned char	*p;
448 	__u32 in[8], buf[4];
449 
450 	/* special hash codes for special dentries */
451 	if ((len <= 2) && (name[0] == '.') &&
452 		(name[1] == '.' || name[1] == '\0'))
453 		return 0;
454 
455 	/* Initialize the default seed for the hash checksum functions */
456 	buf[0] = 0x67452301;
457 	buf[1] = 0xefcdab89;
458 	buf[2] = 0x98badcfe;
459 	buf[3] = 0x10325476;
460 
461 	p = name;
462 	while (1) {
463 		str2hashbuf(p, len, in, 4);
464 		TEA_transform(buf, in);
465 		p += 16;
466 		if (len <= 16)
467 			break;
468 		len -= 16;
469 	}
470 	hash = buf[0];
471 
472 	f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
473 	return f2fs_hash;
474 }
475 
addrs_per_inode(struct f2fs_inode * i)476 unsigned int addrs_per_inode(struct f2fs_inode *i)
477 {
478 	return CUR_ADDRS_PER_INODE(i) - get_inline_xattr_addrs(i);
479 }
480 
481 /*
482  * CRC32
483  */
484 #define CRCPOLY_LE 0xedb88320
485 
f2fs_cal_crc32(u_int32_t crc,void * buf,int len)486 u_int32_t f2fs_cal_crc32(u_int32_t crc, void *buf, int len)
487 {
488 	int i;
489 	unsigned char *p = (unsigned char *)buf;
490 	while (len--) {
491 		crc ^= *p++;
492 		for (i = 0; i < 8; i++)
493 			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
494 	}
495 	return crc;
496 }
497 
f2fs_crc_valid(u_int32_t blk_crc,void * buf,int len)498 int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
499 {
500 	u_int32_t cal_crc = 0;
501 
502 	cal_crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, buf, len);
503 
504 	if (cal_crc != blk_crc)	{
505 		DBG(0,"CRC validation failed: cal_crc = %u, "
506 			"blk_crc = %u buff_size = 0x%x\n",
507 			cal_crc, blk_crc, len);
508 		return -1;
509 	}
510 	return 0;
511 }
512 
f2fs_inode_chksum(struct f2fs_node * node)513 __u32 f2fs_inode_chksum(struct f2fs_node *node)
514 {
515 	struct f2fs_inode *ri = &node->i;
516 	__le32 ino = node->footer.ino;
517 	__le32 gen = ri->i_generation;
518 	__u32 chksum, chksum_seed;
519 	__u32 dummy_cs = 0;
520 	unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
521 	unsigned int cs_size = sizeof(dummy_cs);
522 
523 	chksum = f2fs_cal_crc32(c.chksum_seed, (__u8 *)&ino,
524 							sizeof(ino));
525 	chksum_seed = f2fs_cal_crc32(chksum, (__u8 *)&gen, sizeof(gen));
526 
527 	chksum = f2fs_cal_crc32(chksum_seed, (__u8 *)ri, offset);
528 	chksum = f2fs_cal_crc32(chksum, (__u8 *)&dummy_cs, cs_size);
529 	offset += cs_size;
530 	chksum = f2fs_cal_crc32(chksum, (__u8 *)ri + offset,
531 						F2FS_BLKSIZE - offset);
532 	return chksum;
533 }
534 
535 /*
536  * try to identify the root device
537  */
get_rootdev()538 char *get_rootdev()
539 {
540 #if defined(ANDROID_WINDOWS_HOST) || defined(WITH_ANDROID)
541 	return NULL;
542 #else
543 	struct stat sb;
544 	int fd, ret;
545 	char buf[PATH_MAX + 1];
546 	char *uevent, *ptr;
547 	char *rootdev;
548 
549 	if (stat("/", &sb) == -1)
550 		return NULL;
551 
552 	snprintf(buf, PATH_MAX, "/sys/dev/block/%u:%u/uevent",
553 		major(sb.st_dev), minor(sb.st_dev));
554 
555 	fd = open(buf, O_RDONLY);
556 
557 	if (fd < 0)
558 		return NULL;
559 
560 	ret = lseek(fd, (off_t)0, SEEK_END);
561 	(void)lseek(fd, (off_t)0, SEEK_SET);
562 
563 	if (ret == -1) {
564 		close(fd);
565 		return NULL;
566 	}
567 
568 	uevent = malloc(ret + 1);
569 	ASSERT(uevent);
570 
571 	uevent[ret] = '\0';
572 
573 	ret = read(fd, uevent, ret);
574 	close(fd);
575 
576 	ptr = strstr(uevent, "DEVNAME");
577 	if (!ptr)
578 		return NULL;
579 
580 	ret = sscanf(ptr, "DEVNAME=%s\n", buf);
581 	if (strlen(buf) == 0)
582 		return NULL;
583 
584 	ret = strlen(buf) + 5;
585 	rootdev = malloc(ret + 1);
586 	if (!rootdev)
587 		return NULL;
588 	rootdev[ret] = '\0';
589 
590 	snprintf(rootdev, ret + 1, "/dev/%s", buf);
591 	return rootdev;
592 #endif
593 }
594 
595 /*
596  * device information
597  */
f2fs_init_configuration(void)598 void f2fs_init_configuration(void)
599 {
600 	int i;
601 
602 	memset(&c, 0, sizeof(struct f2fs_configuration));
603 	c.ndevs = 1;
604 	c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK;
605 	c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT;
606 	c.wanted_total_sectors = -1;
607 	c.wanted_sector_size = -1;
608 #ifndef WITH_ANDROID
609 	c.preserve_limits = 1;
610 #endif
611 
612 	for (i = 0; i < MAX_DEVICES; i++) {
613 		c.devices[i].fd = -1;
614 		c.devices[i].sector_size = DEFAULT_SECTOR_SIZE;
615 		c.devices[i].end_blkaddr = -1;
616 		c.devices[i].zoned_model = F2FS_ZONED_NONE;
617 	}
618 
619 	/* calculated by overprovision ratio */
620 	c.segs_per_sec = 1;
621 	c.secs_per_zone = 1;
622 	c.segs_per_zone = 1;
623 	c.vol_label = "";
624 	c.trim = 1;
625 	c.kd = -1;
626 	c.fixed_time = -1;
627 
628 	/* default root owner */
629 	c.root_uid = getuid();
630 	c.root_gid = getgid();
631 }
632 
633 #ifdef HAVE_SETMNTENT
is_mounted(const char * mpt,const char * device)634 static int is_mounted(const char *mpt, const char *device)
635 {
636 	FILE *file = NULL;
637 	struct mntent *mnt = NULL;
638 
639 	file = setmntent(mpt, "r");
640 	if (file == NULL)
641 		return 0;
642 
643 	while ((mnt = getmntent(file)) != NULL) {
644 		if (!strcmp(device, mnt->mnt_fsname)) {
645 #ifdef MNTOPT_RO
646 			if (hasmntopt(mnt, MNTOPT_RO))
647 				c.ro = 1;
648 #endif
649 			break;
650 		}
651 	}
652 	endmntent(file);
653 	return mnt ? 1 : 0;
654 }
655 #endif
656 
f2fs_dev_is_umounted(char * path)657 int f2fs_dev_is_umounted(char *path)
658 {
659 #ifdef ANDROID_WINDOWS_HOST
660 	return 0;
661 #else
662 	struct stat *st_buf;
663 	int is_rootdev = 0;
664 	int ret = 0;
665 	char *rootdev_name = get_rootdev();
666 
667 	if (rootdev_name) {
668 		if (!strcmp(path, rootdev_name))
669 			is_rootdev = 1;
670 		free(rootdev_name);
671 	}
672 
673 	/*
674 	 * try with /proc/mounts fist to detect RDONLY.
675 	 * f2fs_stop_checkpoint makes RO in /proc/mounts while RW in /etc/mtab.
676 	 */
677 #ifdef __linux__
678 	ret = is_mounted("/proc/mounts", path);
679 	if (ret) {
680 		MSG(0, "Info: Mounted device!\n");
681 		return -1;
682 	}
683 #endif
684 #if defined(MOUNTED) || defined(_PATH_MOUNTED)
685 #ifndef MOUNTED
686 #define MOUNTED _PATH_MOUNTED
687 #endif
688 	ret = is_mounted(MOUNTED, path);
689 	if (ret) {
690 		MSG(0, "Info: Mounted device!\n");
691 		return -1;
692 	}
693 #endif
694 	/*
695 	 * If we are supposed to operate on the root device, then
696 	 * also check the mounts for '/dev/root', which sometimes
697 	 * functions as an alias for the root device.
698 	 */
699 	if (is_rootdev) {
700 #ifdef __linux__
701 		ret = is_mounted("/proc/mounts", "/dev/root");
702 		if (ret) {
703 			MSG(0, "Info: Mounted device!\n");
704 			return -1;
705 		}
706 #endif
707 	}
708 
709 	/*
710 	 * If f2fs is umounted with -l, the process can still use
711 	 * the file system. In this case, we should not format.
712 	 */
713 	st_buf = malloc(sizeof(struct stat));
714 	ASSERT(st_buf);
715 
716 	if (stat(path, st_buf) == 0 && S_ISBLK(st_buf->st_mode)) {
717 		int fd = open(path, O_RDONLY | O_EXCL);
718 
719 		if (fd >= 0) {
720 			close(fd);
721 		} else if (errno == EBUSY) {
722 			MSG(0, "\tError: In use by the system!\n");
723 			free(st_buf);
724 			return -1;
725 		}
726 	}
727 	free(st_buf);
728 	return ret;
729 #endif
730 }
731 
f2fs_devs_are_umounted(void)732 int f2fs_devs_are_umounted(void)
733 {
734 	int i;
735 
736 	for (i = 0; i < c.ndevs; i++)
737 		if (f2fs_dev_is_umounted((char *)c.devices[i].path))
738 			return -1;
739 	return 0;
740 }
741 
get_kernel_version(__u8 * version)742 void get_kernel_version(__u8 *version)
743 {
744 	int i;
745 	for (i = 0; i < VERSION_LEN; i++) {
746 		if (version[i] == '\n')
747 			break;
748 	}
749 	memset(version + i, 0, VERSION_LEN + 1 - i);
750 }
751 
get_kernel_uname_version(__u8 * version)752 void get_kernel_uname_version(__u8 *version)
753 {
754 #ifdef HAVE_SYS_UTSNAME_H
755 	struct utsname buf;
756 
757 	memset(version, 0, VERSION_LEN);
758 	if (uname(&buf))
759 		return;
760 
761 #if !defined(WITH_KERNEL_VERSION)
762 	snprintf((char *)version,
763 		VERSION_LEN, "%s %s", buf.release, buf.version);
764 #else
765 	snprintf((char *)version,
766 		VERSION_LEN, "%s", buf.release);
767 #endif
768 #else
769 	memset(version, 0, VERSION_LEN);
770 #endif
771 }
772 
773 #if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
774 #define BLKGETSIZE	_IO(0x12,96)
775 #endif
776 
777 #if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
778 #define BLKGETSIZE64	_IOR(0x12,114, size_t)
779 #endif
780 
781 #if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
782 #define BLKSSZGET	_IO(0x12,104)
783 #endif
784 
785 #if defined(__APPLE__)
786 #include <sys/disk.h>
787 #define BLKGETSIZE	DKIOCGETBLOCKCOUNT
788 #define BLKSSZGET	DKIOCGETBLOCKCOUNT
789 #endif /* APPLE_DARWIN */
790 
791 #ifndef ANDROID_WINDOWS_HOST
get_device_info(int i)792 int get_device_info(int i)
793 {
794 	int32_t fd = 0;
795 	uint32_t sector_size;
796 #ifndef BLKGETSIZE64
797 	uint32_t total_sectors;
798 #endif
799 	struct stat *stat_buf;
800 #ifdef HDIO_GETGIO
801 	struct hd_geometry geom;
802 #endif
803 #if !defined(WITH_ANDROID) && defined(__linux__)
804 	sg_io_hdr_t io_hdr;
805 	unsigned char reply_buffer[96] = {0};
806 	unsigned char model_inq[6] = {MODELINQUIRY};
807 #endif
808 	struct device_info *dev = c.devices + i;
809 
810 	if (c.sparse_mode) {
811 		fd = open(dev->path, O_RDWR | O_CREAT | O_BINARY, 0644);
812 		if (fd < 0) {
813 			MSG(0, "\tError: Failed to open a sparse file!\n");
814 			return -1;
815 		}
816 	}
817 
818 	stat_buf = malloc(sizeof(struct stat));
819 	ASSERT(stat_buf);
820 
821 	if (!c.sparse_mode) {
822 		if (stat(dev->path, stat_buf) < 0 ) {
823 			MSG(0, "\tError: Failed to get the device stat!\n");
824 			free(stat_buf);
825 			return -1;
826 		}
827 
828 		if (S_ISBLK(stat_buf->st_mode) && !c.force)
829 			fd = open(dev->path, O_RDWR | O_EXCL);
830 		else
831 			fd = open(dev->path, O_RDWR);
832 	}
833 	if (fd < 0) {
834 		MSG(0, "\tError: Failed to open the device!\n");
835 		free(stat_buf);
836 		return -1;
837 	}
838 
839 	dev->fd = fd;
840 
841 	if (c.sparse_mode) {
842 		if (f2fs_init_sparse_file()) {
843 			free(stat_buf);
844 			return -1;
845 		}
846 	}
847 
848 	if (c.kd == -1) {
849 #if !defined(WITH_ANDROID) && defined(__linux__)
850 		c.kd = open("/proc/version", O_RDONLY);
851 #endif
852 		if (c.kd < 0) {
853 			MSG(0, "\tInfo: No support kernel version!\n");
854 			c.kd = -2;
855 		}
856 	}
857 
858 	if (c.sparse_mode) {
859 		dev->total_sectors = c.device_size / dev->sector_size;
860 	} else if (S_ISREG(stat_buf->st_mode)) {
861 		dev->total_sectors = stat_buf->st_size / dev->sector_size;
862 	} else if (S_ISBLK(stat_buf->st_mode)) {
863 #ifdef BLKSSZGET
864 		if (ioctl(fd, BLKSSZGET, &sector_size) < 0)
865 			MSG(0, "\tError: Using the default sector size\n");
866 		else if (dev->sector_size < sector_size)
867 			dev->sector_size = sector_size;
868 #endif
869 #ifdef BLKGETSIZE64
870 		if (ioctl(fd, BLKGETSIZE64, &dev->total_sectors) < 0) {
871 			MSG(0, "\tError: Cannot get the device size\n");
872 			free(stat_buf);
873 			return -1;
874 		}
875 #else
876 		if (ioctl(fd, BLKGETSIZE, &total_sectors) < 0) {
877 			MSG(0, "\tError: Cannot get the device size\n");
878 			free(stat_buf);
879 			return -1;
880 		}
881 		dev->total_sectors = total_sectors;
882 #endif
883 		dev->total_sectors /= dev->sector_size;
884 
885 		if (i == 0) {
886 #ifdef HDIO_GETGIO
887 			if (ioctl(fd, HDIO_GETGEO, &geom) < 0)
888 				c.start_sector = 0;
889 			else
890 				c.start_sector = geom.start;
891 #else
892 			c.start_sector = 0;
893 #endif
894 		}
895 
896 #if !defined(WITH_ANDROID) && defined(__linux__)
897 		/* Send INQUIRY command */
898 		memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
899 		io_hdr.interface_id = 'S';
900 		io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
901 		io_hdr.dxfer_len = sizeof(reply_buffer);
902 		io_hdr.dxferp = reply_buffer;
903 		io_hdr.cmd_len = sizeof(model_inq);
904 		io_hdr.cmdp = model_inq;
905 		io_hdr.timeout = 1000;
906 
907 		if (!ioctl(fd, SG_IO, &io_hdr)) {
908 			MSG(0, "Info: [%s] Disk Model: %.16s\n",
909 					dev->path, reply_buffer+16);
910 		}
911 #endif
912 	} else {
913 		MSG(0, "\tError: Volume type is not supported!!!\n");
914 		free(stat_buf);
915 		return -1;
916 	}
917 
918 	if (!c.sector_size) {
919 		c.sector_size = dev->sector_size;
920 		c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
921 	} else if (c.sector_size != c.devices[i].sector_size) {
922 		MSG(0, "\tError: Different sector sizes!!!\n");
923 		free(stat_buf);
924 		return -1;
925 	}
926 
927 #if !defined(WITH_ANDROID) && defined(__linux__)
928 	if (S_ISBLK(stat_buf->st_mode))
929 		f2fs_get_zoned_model(i);
930 
931 	if (dev->zoned_model != F2FS_ZONED_NONE) {
932 		if (dev->zoned_model == F2FS_ZONED_HM)
933 			c.zoned_model = F2FS_ZONED_HM;
934 
935 		if (f2fs_get_zone_blocks(i)) {
936 			MSG(0, "\tError: Failed to get number of blocks per zone\n");
937 			free(stat_buf);
938 			return -1;
939 		}
940 
941 		if (f2fs_check_zones(i)) {
942 			MSG(0, "\tError: Failed to check zone configuration\n");
943 			free(stat_buf);
944 			return -1;
945 		}
946 		MSG(0, "Info: Host-%s zoned block device:\n",
947 				(dev->zoned_model == F2FS_ZONED_HA) ?
948 					"aware" : "managed");
949 		MSG(0, "      %u zones, %u randomly writeable zones\n",
950 				dev->nr_zones, dev->nr_rnd_zones);
951 		MSG(0, "      %lu blocks per zone\n",
952 				dev->zone_blocks);
953 	}
954 #endif
955 	/* adjust wanted_total_sectors */
956 	if (c.wanted_total_sectors != -1) {
957 		MSG(0, "Info: wanted sectors = %"PRIu64" (in %"PRIu64" bytes)\n",
958 				c.wanted_total_sectors, c.wanted_sector_size);
959 		if (c.wanted_sector_size == -1) {
960 			c.wanted_sector_size = dev->sector_size;
961 		} else if (dev->sector_size != c.wanted_sector_size) {
962 			c.wanted_total_sectors *= c.wanted_sector_size;
963 			c.wanted_total_sectors /= dev->sector_size;
964 		}
965 	}
966 
967 	c.total_sectors += dev->total_sectors;
968 	free(stat_buf);
969 	return 0;
970 }
971 
972 #else
973 
974 #include "windows.h"
975 #include "winioctl.h"
976 
977 #if (_WIN32_WINNT >= 0x0500)
978 #define HAVE_GET_FILE_SIZE_EX 1
979 #endif
980 
win_get_device_size(const char * file,uint64_t * device_size)981 static int win_get_device_size(const char *file, uint64_t *device_size)
982 {
983 	HANDLE dev;
984 	PARTITION_INFORMATION pi;
985 	DISK_GEOMETRY gi;
986 	DWORD retbytes;
987 #ifdef HAVE_GET_FILE_SIZE_EX
988 	LARGE_INTEGER filesize;
989 #else
990 	DWORD filesize;
991 #endif /* HAVE_GET_FILE_SIZE_EX */
992 
993 	dev = CreateFile(file, GENERIC_READ,
994 			FILE_SHARE_READ | FILE_SHARE_WRITE ,
995 			NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  NULL);
996 
997 	if (dev == INVALID_HANDLE_VALUE)
998 		return EBADF;
999 	if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
1000 				&pi, sizeof(PARTITION_INFORMATION),
1001 				&pi, sizeof(PARTITION_INFORMATION),
1002 				&retbytes, NULL)) {
1003 
1004 		*device_size = 	pi.PartitionLength.QuadPart;
1005 
1006 	} else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
1007 				&gi, sizeof(DISK_GEOMETRY),
1008 				&gi, sizeof(DISK_GEOMETRY),
1009 				&retbytes, NULL)) {
1010 
1011 		*device_size = gi.BytesPerSector *
1012 			gi.SectorsPerTrack *
1013 			gi.TracksPerCylinder *
1014 			gi.Cylinders.QuadPart;
1015 
1016 #ifdef HAVE_GET_FILE_SIZE_EX
1017 	} else if (GetFileSizeEx(dev, &filesize)) {
1018 		*device_size = filesize.QuadPart;
1019 	}
1020 #else
1021 	} else {
1022 		filesize = GetFileSize(dev, NULL);
1023 		if (INVALID_FILE_SIZE != filesize)
1024 			return -1;
1025 		*device_size = filesize;
1026 	}
1027 #endif /* HAVE_GET_FILE_SIZE_EX */
1028 
1029 	CloseHandle(dev);
1030 	return 0;
1031 }
1032 
get_device_info(int i)1033 int get_device_info(int i)
1034 {
1035 	struct device_info *dev = c.devices + i;
1036 	uint64_t device_size = 0;
1037 	int32_t fd = 0;
1038 
1039 	/* Block device target is not supported on Windows. */
1040 	if (!c.sparse_mode) {
1041 		if (win_get_device_size(dev->path, &device_size)) {
1042 			MSG(0, "\tError: Failed to get device size!\n");
1043 			return -1;
1044 		}
1045 	} else {
1046 		device_size = c.device_size;
1047 	}
1048 	if (c.sparse_mode) {
1049 		fd = open((char *)dev->path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
1050 	} else {
1051 		fd = open((char *)dev->path, O_RDWR | O_BINARY);
1052 	}
1053 	if (fd < 0) {
1054 		MSG(0, "\tError: Failed to open the device!\n");
1055 		return -1;
1056 	}
1057 	dev->fd = fd;
1058 	dev->total_sectors = device_size / dev->sector_size;
1059 	c.start_sector = 0;
1060 	c.sector_size = dev->sector_size;
1061 	c.sectors_per_blk = F2FS_BLKSIZE / c.sector_size;
1062 	c.total_sectors += dev->total_sectors;
1063 
1064 	return 0;
1065 }
1066 #endif
1067 
f2fs_get_device_info(void)1068 int f2fs_get_device_info(void)
1069 {
1070 	int i;
1071 
1072 	for (i = 0; i < c.ndevs; i++)
1073 		if (get_device_info(i))
1074 			return -1;
1075 
1076 	if (c.wanted_total_sectors < c.total_sectors) {
1077 		MSG(0, "Info: total device sectors = %"PRIu64" (in %u bytes)\n",
1078 				c.total_sectors, c.sector_size);
1079 		c.total_sectors = c.wanted_total_sectors;
1080 		c.devices[0].total_sectors = c.total_sectors;
1081 	}
1082 	if (c.total_sectors * c.sector_size >
1083 		(u_int64_t)F2FS_MAX_SEGMENT * 2 * 1024 * 1024) {
1084 		MSG(0, "\tError: F2FS can support 16TB at most!!!\n");
1085 		return -1;
1086 	}
1087 
1088 	for (i = 0; i < c.ndevs; i++) {
1089 		if (c.devices[i].zoned_model != F2FS_ZONED_NONE) {
1090 			if (c.zone_blocks &&
1091 				c.zone_blocks != c.devices[i].zone_blocks) {
1092 				MSG(0, "\tError: not support different zone sizes!!!\n");
1093 				return -1;
1094 			}
1095 			c.zone_blocks = c.devices[i].zone_blocks;
1096 		}
1097 	}
1098 
1099 	/*
1100 	 * Align sections to the device zone size
1101 	 * and align F2FS zones to the device zones.
1102 	 */
1103 	if (c.zone_blocks) {
1104 		c.segs_per_sec = c.zone_blocks / DEFAULT_BLOCKS_PER_SEGMENT;
1105 		c.secs_per_zone = 1;
1106 	} else {
1107 		c.zoned_mode = 0;
1108 	}
1109 
1110 	c.segs_per_zone = c.segs_per_sec * c.secs_per_zone;
1111 
1112 	MSG(0, "Info: Segments per section = %d\n", c.segs_per_sec);
1113 	MSG(0, "Info: Sections per zone = %d\n", c.secs_per_zone);
1114 	MSG(0, "Info: sector size = %u\n", c.sector_size);
1115 	MSG(0, "Info: total sectors = %"PRIu64" (%"PRIu64" MB)\n",
1116 				c.total_sectors, (c.total_sectors *
1117 					(c.sector_size >> 9)) >> 11);
1118 	return 0;
1119 }
1120