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