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, §or_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