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