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