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 #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  */
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    264 int get_bits_in_byte(unsigned char n)
    265 {
    266 	return bits_in_byte[n];
    267 }
    268 
    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 
    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 
    291 int test_bit_le(u32 nr, const u8 *addr)
    292 {
    293 	return ((1 << (nr & 7)) & (addr[nr >> 3]));
    294 }
    295 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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  */
    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 
    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 
    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 
    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 
    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  */
    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  */
    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
    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 	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 
    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 
    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 
    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
    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 
    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 
   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 
   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