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