]> git.sven.stormbind.net Git - sven/exfatprogs.git/blob - mkfs/mkfs.c
Update upstream source from tag 'upstream/1.0.4'
[sven/exfatprogs.git] / mkfs / mkfs.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2019 Namjae Jeon <linkinjeon@kernel.org>
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdbool.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <sys/ioctl.h>
14 #include <fcntl.h>
15 #include <getopt.h>
16 #include <inttypes.h>
17 #include <errno.h>
18 #include <locale.h>
19 #include <time.h>
20
21 #include "exfat_ondisk.h"
22 #include "libexfat.h"
23 #include "mkfs.h"
24
25 struct exfat_mkfs_info finfo;
26
27 /* random serial generator based on current time */
28 static unsigned int get_new_serial(void)
29 {
30         struct timespec ts;
31
32         if (clock_gettime(CLOCK_REALTIME, &ts)) {
33                 /* set 0000-0000 on error */
34                 ts.tv_sec = 0;
35                 ts.tv_nsec = 0;
36         }
37
38         return (unsigned int)(ts.tv_nsec << 12 | ts.tv_sec);
39 }
40
41 static void exfat_setup_boot_sector(struct pbr *ppbr,
42                 struct exfat_blk_dev *bd, struct exfat_user_input *ui)
43 {
44         struct bpb64 *pbpb = &ppbr->bpb;
45         struct bsx64 *pbsx = &ppbr->bsx;
46         unsigned int i;
47
48         /* Fill exfat BIOS paramemter block */
49         pbpb->jmp_boot[0] = 0xeb;
50         pbpb->jmp_boot[1] = 0x76;
51         pbpb->jmp_boot[2] = 0x90;
52         memcpy(pbpb->oem_name, "EXFAT   ", 8);
53         memset(pbpb->res_zero, 0, 53);
54
55         /* Fill exfat extend BIOS paramemter block */
56         pbsx->vol_offset = 0;
57         pbsx->vol_length = cpu_to_le64(bd->size / bd->sector_size);
58         pbsx->fat_offset = cpu_to_le32(finfo.fat_byte_off / bd->sector_size);
59         pbsx->fat_length = cpu_to_le32(finfo.fat_byte_len / bd->sector_size);
60         pbsx->clu_offset = cpu_to_le32(finfo.clu_byte_off / bd->sector_size);
61         pbsx->clu_count = cpu_to_le32(finfo.total_clu_cnt);
62         pbsx->root_cluster = cpu_to_le32(finfo.root_start_clu);
63         pbsx->vol_serial = cpu_to_le32(finfo.volume_serial);
64         pbsx->vol_flags = 0;
65         pbsx->sect_size_bits = bd->sector_size_bits;
66         pbsx->sect_per_clus_bits = 0;
67         /* Compute base 2 logarithm of ui->cluster_size / bd->sector_size */
68         for (i = ui->cluster_size / bd->sector_size; i > 1; i /= 2)
69                 pbsx->sect_per_clus_bits++;
70         pbsx->num_fats = 1;
71         /* fs_version[0] : minor and fs_version[1] : major */
72         pbsx->fs_version[0] = 0;
73         pbsx->fs_version[1] = 1;
74         memset(pbsx->reserved2, 0, 7);
75
76         memset(ppbr->boot_code, 0, 390);
77         ppbr->signature = cpu_to_le16(PBR_SIGNATURE);
78
79         exfat_debug("Volume Length(sectors) : %" PRIu64 "\n",
80                 le64_to_cpu(pbsx->vol_length));
81         exfat_debug("FAT Offset(sector offset) : %u\n",
82                 le32_to_cpu(pbsx->fat_offset));
83         exfat_debug("FAT Length(sectors) : %u\n",
84                 le32_to_cpu(pbsx->fat_length));
85         exfat_debug("Cluster Heap Offset (sector offset) : %u\n",
86                 le32_to_cpu(pbsx->clu_offset));
87         exfat_debug("Cluster Count (sectors) : %u\n",
88                 le32_to_cpu(pbsx->clu_count));
89         exfat_debug("Root Cluster (cluster offset) : %u\n",
90                 le32_to_cpu(pbsx->root_cluster));
91         exfat_debug("Sector Size Bits : %u\n",
92                 pbsx->sect_size_bits);
93         exfat_debug("Sector per Cluster bits : %u\n",
94                 pbsx->sect_per_clus_bits);
95 }
96
97 static int exfat_write_sector(struct exfat_blk_dev *bd, void *buf,
98                 unsigned int sec_off)
99 {
100         int bytes;
101         unsigned long long offset = sec_off * bd->sector_size;
102
103         lseek(bd->dev_fd, offset, SEEK_SET);
104         bytes = write(bd->dev_fd, buf, bd->sector_size);
105         if (bytes != (int)bd->sector_size) {
106                 exfat_err("write failed, sec_off : %u, bytes : %d\n", sec_off,
107                         bytes);
108                 return -1;
109         }
110         return 0;
111 }
112
113 static int exfat_write_boot_sector(struct exfat_blk_dev *bd,
114                 struct exfat_user_input *ui, unsigned int *checksum,
115                 bool is_backup)
116 {
117         struct pbr *ppbr;
118         unsigned int sec_idx = BOOT_SEC_IDX;
119         int ret = 0;
120
121         if (is_backup)
122                 sec_idx += BACKUP_BOOT_SEC_IDX;
123
124         ppbr = malloc(sizeof(struct pbr));
125         if (!ppbr) {
126                 exfat_err("Cannot allocate pbr: out of memory\n");
127                 return -1;
128         }
129         memset(ppbr, 0, sizeof(struct pbr));
130
131         exfat_setup_boot_sector(ppbr, bd, ui);
132
133         /* write main boot sector */
134         ret = exfat_write_sector(bd, ppbr, sec_idx);
135         if (ret < 0) {
136                 exfat_err("main boot sector write failed\n");
137                 ret = -1;
138                 goto free_ppbr;
139         }
140
141         boot_calc_checksum((unsigned char *)ppbr, sizeof(struct pbr),
142                 true, checksum);
143
144 free_ppbr:
145         free(ppbr);
146         return ret;
147 }
148
149 static int exfat_write_extended_boot_sectors(struct exfat_blk_dev *bd,
150                 unsigned int *checksum, bool is_backup)
151 {
152         struct exbs eb;
153         int i;
154         unsigned int sec_idx = EXBOOT_SEC_IDX;
155
156         if (is_backup)
157                 sec_idx += BACKUP_BOOT_SEC_IDX;
158
159         memset(&eb, 0, sizeof(struct exbs));
160         eb.signature = cpu_to_le16(PBR_SIGNATURE);
161         for (i = 0; i < EXBOOT_SEC_NUM; i++) {
162                 if (exfat_write_sector(bd, &eb, sec_idx++)) {
163                         exfat_err("extended boot sector write failed\n");
164                         return -1;
165                 }
166
167                 boot_calc_checksum((unsigned char *) &eb, sizeof(struct exbs),
168                         false, checksum);
169         }
170
171         return 0;
172 }
173
174 static int exfat_write_oem_sector(struct exfat_blk_dev *bd,
175                 unsigned int *checksum, bool is_backup)
176 {
177         char *oem;
178         int ret = 0;
179         unsigned int sec_idx = OEM_SEC_IDX;
180
181         oem = malloc(bd->sector_size);
182         if (!oem)
183                 return -1;
184
185         if (is_backup)
186                 sec_idx += BACKUP_BOOT_SEC_IDX;
187
188         memset(oem, 0xFF, bd->sector_size);
189         ret = exfat_write_sector(bd, oem, sec_idx);
190         if (ret) {
191                 exfat_err("oem sector write failed\n");
192                 ret = -1;
193                 goto free_oem;
194         }
195
196         boot_calc_checksum((unsigned char *)oem, bd->sector_size, false,
197                 checksum);
198
199         /* Zero out reserved sector */
200         memset(oem, 0, bd->sector_size);
201         ret = exfat_write_sector(bd, oem, sec_idx + 1);
202         if (ret) {
203                 exfat_err("reserved sector write failed\n");
204                 ret = -1;
205                 goto free_oem;
206         }
207
208         boot_calc_checksum((unsigned char *)oem, bd->sector_size, false,
209                 checksum);
210
211 free_oem:
212         free(oem);
213         return ret;
214 }
215
216 static int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
217                 unsigned int checksum, bool is_backup)
218 {
219         __le32 *checksum_buf;
220         int ret = 0;
221         unsigned int i;
222         unsigned int sec_idx = CHECKSUM_SEC_IDX;
223
224         checksum_buf = malloc(bd->sector_size);
225         if (!checksum_buf)
226                 return -1;
227
228         if (is_backup)
229                 sec_idx += BACKUP_BOOT_SEC_IDX;
230
231         for (i = 0; i < bd->sector_size / sizeof(int); i++)
232                 checksum_buf[i] = cpu_to_le32(checksum);
233
234         ret = exfat_write_sector(bd, checksum_buf, sec_idx);
235         if (ret) {
236                 exfat_err("checksum sector write failed\n");
237                 goto free;
238         }
239
240 free:
241         free(checksum_buf);
242         return ret;
243 }
244
245 static int exfat_create_volume_boot_record(struct exfat_blk_dev *bd,
246                 struct exfat_user_input *ui, bool is_backup)
247 {
248         unsigned int checksum = 0;
249         int ret;
250
251         ret = exfat_write_boot_sector(bd, ui, &checksum, is_backup);
252         if (ret)
253                 return ret;
254         ret = exfat_write_extended_boot_sectors(bd, &checksum, is_backup);
255         if (ret)
256                 return ret;
257         ret = exfat_write_oem_sector(bd, &checksum, is_backup);
258         if (ret)
259                 return ret;
260
261         return exfat_write_checksum_sector(bd, checksum, is_backup);
262 }
263
264 static int write_fat_entry(int fd, __le32 clu,
265                 unsigned long long offset)
266 {
267         int nbyte;
268
269         lseek(fd, finfo.fat_byte_off + (offset * sizeof(__le32)), SEEK_SET);
270         nbyte = write(fd, (__u8 *) &clu, sizeof(__le32));
271         if (nbyte != sizeof(int)) {
272                 exfat_err("write failed, offset : %llu, clu : %x\n",
273                         offset, clu);
274                 return -1;
275         }
276
277         return 0;
278 }
279
280 static int write_fat_entries(struct exfat_user_input *ui, int fd,
281                 unsigned int clu, unsigned int length)
282 {
283         int ret;
284         unsigned int count;
285
286         count = clu + round_up(length, ui->cluster_size) / ui->cluster_size;
287
288         for (; clu < count - 1; clu++) {
289                 ret = write_fat_entry(fd, cpu_to_le32(clu + 1), clu);
290                 if (ret)
291                         return ret;
292         }
293
294         ret = write_fat_entry(fd, cpu_to_le32(EXFAT_EOF_CLUSTER), clu);
295         if (ret)
296                 return ret;
297
298         return clu;
299 }
300
301 static int exfat_create_fat_table(struct exfat_blk_dev *bd,
302                 struct exfat_user_input *ui)
303 {
304         int ret, clu;
305
306         /* fat entry 0 should be media type field(0xF8) */
307         ret = write_fat_entry(bd->dev_fd, cpu_to_le32(0xfffffff8), 0);
308         if (ret) {
309                 exfat_err("fat 0 entry write failed\n");
310                 return ret;
311         }
312
313         /* fat entry 1 is historical precedence(0xFFFFFFFF) */
314         ret = write_fat_entry(bd->dev_fd, cpu_to_le32(0xffffffff), 1);
315         if (ret) {
316                 exfat_err("fat 1 entry write failed\n");
317                 return ret;
318         }
319
320         /* write bitmap entries */
321         clu = write_fat_entries(ui, bd->dev_fd, EXFAT_FIRST_CLUSTER,
322                 finfo.bitmap_byte_len);
323         if (clu < 0)
324                 return ret;
325
326         /* write upcase table entries */
327         clu = write_fat_entries(ui, bd->dev_fd, clu + 1, finfo.ut_byte_len);
328         if (clu < 0)
329                 return ret;
330
331         /* write root directory entries */
332         clu = write_fat_entries(ui, bd->dev_fd, clu + 1, finfo.root_byte_len);
333         if (clu < 0)
334                 return ret;
335
336         finfo.used_clu_cnt = clu + 1;
337         exfat_debug("Total used cluster count : %d\n", finfo.used_clu_cnt);
338
339         return ret;
340 }
341
342 static int exfat_create_bitmap(struct exfat_blk_dev *bd)
343 {
344         char *bitmap;
345         unsigned int i, nbytes;
346
347         bitmap = calloc(finfo.bitmap_byte_len, sizeof(*bitmap));
348         if (!bitmap)
349                 return -1;
350
351         for (i = 0; i < finfo.used_clu_cnt - EXFAT_FIRST_CLUSTER; i++)
352                 exfat_set_bit(bd, bitmap, i);
353
354         lseek(bd->dev_fd, finfo.bitmap_byte_off, SEEK_SET);
355         nbytes = write(bd->dev_fd, bitmap, finfo.bitmap_byte_len);
356         if (nbytes != finfo.bitmap_byte_len) {
357                 exfat_err("write failed, nbytes : %d, bitmap_len : %d\n",
358                         nbytes, finfo.bitmap_byte_len);
359                 free(bitmap);
360                 return -1;
361         }
362
363         free(bitmap);
364         return 0;
365 }
366
367 static int exfat_create_root_dir(struct exfat_blk_dev *bd,
368                 struct exfat_user_input *ui)
369 {
370         struct exfat_dentry ed[3];
371         int dentries_len = sizeof(struct exfat_dentry) * 3;
372         int nbytes;
373
374         /* Set volume label entry */
375         ed[0].type = EXFAT_VOLUME;
376         memset(ed[0].vol_label, 0, 22);
377         memcpy(ed[0].vol_label, ui->volume_label, ui->volume_label_len);
378         ed[0].vol_char_cnt = ui->volume_label_len/2;
379
380         /* Set bitmap entry */
381         ed[1].type = EXFAT_BITMAP;
382         ed[1].bitmap_flags = 0;
383         ed[1].bitmap_start_clu = cpu_to_le32(EXFAT_FIRST_CLUSTER);
384         ed[1].bitmap_size = cpu_to_le64(finfo.bitmap_byte_len);
385
386         /* Set upcase table entry */
387         ed[2].type = EXFAT_UPCASE;
388         ed[2].upcase_checksum = cpu_to_le32(0xe619d30d);
389         ed[2].upcase_start_clu = cpu_to_le32(finfo.ut_start_clu);
390         ed[2].upcase_size = cpu_to_le64(EXFAT_UPCASE_TABLE_SIZE);
391
392         lseek(bd->dev_fd, finfo.root_byte_off, SEEK_SET);
393         nbytes = write(bd->dev_fd, ed, dentries_len);
394         if (nbytes != dentries_len) {
395                 exfat_err("write failed, nbytes : %d, dentries_len : %d\n",
396                         nbytes, dentries_len);
397                 return -1;
398         }
399
400         return 0;
401 }
402
403 static void usage(void)
404 {
405         fprintf(stderr, "Usage: mkfs.exfat\n");
406         fprintf(stderr, "\t-L | --volume-label=label                              Set volume label\n");
407         fprintf(stderr, "\t-c | --cluster-size=size(or suffixed by 'K' or 'M')    Specify cluster size\n");
408         fprintf(stderr, "\t-b | --boundary-align=size(or suffixed by 'K' or 'M')  Specify boundary alignment\n");
409         fprintf(stderr, "\t-f | --full-format                                     Full format\n");
410         fprintf(stderr, "\t-V | --version                                         Show version\n");
411         fprintf(stderr, "\t-v | --verbose                                         Print debug\n");
412         fprintf(stderr, "\t-h | --help                                            Show help\n");
413
414         exit(EXIT_FAILURE);
415 }
416
417 static struct option opts[] = {
418         {"volume-label",        required_argument,      NULL,   'L' },
419         {"cluster-size",        required_argument,      NULL,   'c' },
420         {"boundary-align",      required_argument,      NULL,   'b' },
421         {"full-format",         no_argument,            NULL,   'f' },
422         {"version",             no_argument,            NULL,   'V' },
423         {"verbose",             no_argument,            NULL,   'v' },
424         {"help",                no_argument,            NULL,   'h' },
425         {"?",                   no_argument,            NULL,   '?' },
426         {NULL,                  0,                      NULL,    0  }
427 };
428
429 static int exfat_build_mkfs_info(struct exfat_blk_dev *bd,
430                 struct exfat_user_input *ui)
431 {
432         int clu_len;
433
434         if (ui->boundary_align < bd->sector_size) {
435                 exfat_err("boundary alignment is too small (min %d)\n",
436                                 bd->sector_size);
437                 return -1;
438         }
439         finfo.fat_byte_off = round_up(24 * bd->sector_size,
440                         ui->boundary_align);
441         finfo.fat_byte_len = round_up((bd->num_clusters * sizeof(int)),
442                 ui->cluster_size);
443         finfo.clu_byte_off = round_up(finfo.fat_byte_off + finfo.fat_byte_len,
444                 ui->boundary_align);
445         if (bd->size <= finfo.clu_byte_off) {
446                 exfat_err("boundary alignment is too big\n");
447                 return -1;
448         }
449         finfo.total_clu_cnt = (bd->size - finfo.clu_byte_off) /
450                 ui->cluster_size;
451         if (finfo.total_clu_cnt > EXFAT_MAX_NUM_CLUSTER) {
452                 exfat_err("cluster size is too small\n");
453                 return -1;
454         }
455
456         finfo.bitmap_byte_off = finfo.clu_byte_off;
457         finfo.bitmap_byte_len = round_up(finfo.total_clu_cnt, 8) / 8;
458         clu_len = round_up(finfo.bitmap_byte_len, ui->cluster_size);
459
460         finfo.ut_start_clu = EXFAT_FIRST_CLUSTER + clu_len / ui->cluster_size;
461         finfo.ut_byte_off = finfo.bitmap_byte_off + clu_len;
462         finfo.ut_byte_len = EXFAT_UPCASE_TABLE_SIZE;
463         clu_len = round_up(finfo.ut_byte_len, ui->cluster_size);
464
465         finfo.root_start_clu = finfo.ut_start_clu + clu_len / ui->cluster_size;
466         finfo.root_byte_off = finfo.ut_byte_off + clu_len;
467         finfo.root_byte_len = sizeof(struct exfat_dentry) * 3;
468         finfo.volume_serial = get_new_serial();
469
470         return 0;
471 }
472
473 static int exfat_zero_out_disk(struct exfat_blk_dev *bd,
474                 struct exfat_user_input *ui)
475 {
476         int nbytes;
477         unsigned long long total_written = 0;
478         char *buf;
479         unsigned int chunk_size = ui->cluster_size;
480         unsigned long long size;
481
482         if (ui->quick)
483                 size = finfo.root_byte_off + chunk_size;
484         else
485                 size = bd->size;
486
487         buf = malloc(chunk_size);
488         if (!buf)
489                 return -1;
490
491         memset(buf, 0, chunk_size);
492         lseek(bd->dev_fd, 0, SEEK_SET);
493         do {
494
495                 nbytes = write(bd->dev_fd, buf, chunk_size);
496                 if (nbytes <= 0) {
497                         if (nbytes < 0)
498                                 exfat_err("write failed(errno : %d)\n", errno);
499                         break;
500                 }
501                 total_written += nbytes;
502         } while (total_written < size);
503
504         free(buf);
505         exfat_debug("zero out written size : %llu, disk size : %llu\n",
506                 total_written, bd->size);
507         return 0;
508 }
509
510 static int make_exfat(struct exfat_blk_dev *bd, struct exfat_user_input *ui)
511 {
512         int ret;
513
514         exfat_info("Creating exFAT filesystem(%s, cluster size=%u)\n\n",
515                 ui->dev_name, ui->cluster_size);
516
517         exfat_info("Writing volume boot record: ");
518         ret = exfat_create_volume_boot_record(bd, ui, 0);
519         exfat_info("%s\n", ret ? "failed" : "done");
520         if (ret)
521                 return ret;
522
523         exfat_info("Writing backup volume boot record: ");
524         /* backup sector */
525         ret = exfat_create_volume_boot_record(bd, ui, 1);
526         exfat_info("%s\n", ret ? "failed" : "done");
527         if (ret)
528                 return ret;
529
530         exfat_info("Fat table creation: ");
531         ret = exfat_create_fat_table(bd, ui);
532         exfat_info("%s\n", ret ? "failed" : "done");
533         if (ret)
534                 return ret;
535
536         exfat_info("Allocation bitmap creation: ");
537         ret = exfat_create_bitmap(bd);
538         exfat_info("%s\n", ret ? "failed" : "done");
539         if (ret)
540                 return ret;
541
542         exfat_info("Upcase table creation: ");
543         ret = exfat_create_upcase_table(bd);
544         exfat_info("%s\n", ret ? "failed" : "done");
545         if (ret)
546                 return ret;
547
548         exfat_info("Writing root directory entry: ");
549         ret = exfat_create_root_dir(bd, ui);
550         exfat_info("%s\n", ret ? "failed" : "done");
551         if (ret)
552                 return ret;
553
554         return 0;
555 }
556
557 static long long parse_size(const char *size)
558 {
559         char *data_unit;
560         unsigned long long byte_size = strtoull(size, &data_unit, 0);
561
562         switch (*data_unit) {
563         case 'M':
564         case 'm':
565                 byte_size <<= 20;
566                 break;
567         case 'K':
568         case 'k':
569                 byte_size <<= 10;
570                 break;
571         case '\0':
572                 break;
573         default:
574                 exfat_err("Wrong unit input('%c') for size\n",
575                                 *data_unit);
576                 return -EINVAL;
577         }
578
579         return byte_size;
580 }
581
582 int main(int argc, char *argv[])
583 {
584         int c;
585         int ret = EXIT_FAILURE;
586         struct exfat_blk_dev bd;
587         struct exfat_user_input ui;
588         bool version_only = false;
589
590         init_user_input(&ui);
591
592         if (!setlocale(LC_CTYPE, ""))
593                 exfat_err("failed to init locale/codeset\n");
594
595         opterr = 0;
596         while ((c = getopt_long(argc, argv, "n:L:c:b:fVvh", opts, NULL)) != EOF)
597                 switch (c) {
598                 /*
599                  * Make 'n' option fallthrough to 'L' option for for backward
600                  * compatibility with old utils.
601                  */
602                 case 'n':
603                 case 'L':
604                 {
605                         ret = exfat_utf16_enc(optarg,
606                                 ui.volume_label, sizeof(ui.volume_label));
607                         if (ret < 0)
608                                 goto out;
609
610                         ui.volume_label_len = ret;
611                         break;
612                 }
613                 case 'c':
614                         ret = parse_size(optarg);
615                         if (ret < 0)
616                                 goto out;
617                         else if (ret & (ret - 1)) {
618                                 exfat_err("cluster size(%d) is not a power of 2)\n",
619                                         ret);
620                                 goto out;
621                         } else if (ret > EXFAT_MAX_CLUSTER_SIZE) {
622                                 exfat_err("cluster size(%d) exceeds max cluster size(%d)\n",
623                                         ui.cluster_size, EXFAT_MAX_CLUSTER_SIZE);
624                                 goto out;
625                         }
626                         ui.cluster_size = ret;
627                         break;
628                 case 'b':
629                         ret = parse_size(optarg);
630                         if (ret < 0)
631                                 goto out;
632                         else if (ret & (ret - 1)) {
633                                 exfat_err("boundary align(%d) is not a power of 2)\n",
634                                         ret);
635                                 goto out;
636                         }
637                         ui.boundary_align = ret;
638                         break;
639                 case 'f':
640                         ui.quick = false;
641                         break;
642                 case 'V':
643                         version_only = true;
644                         break;
645                 case 'v':
646                         print_level = EXFAT_DEBUG;
647                         break;
648                 case '?':
649                 case 'h':
650                 default:
651                         usage();
652         }
653
654         show_version();
655         if (version_only)
656                 exit(EXIT_FAILURE);
657
658         if (argc - optind != 1) {
659                 usage();
660         }
661
662         memset(ui.dev_name, 0, sizeof(ui.dev_name));
663         snprintf(ui.dev_name, sizeof(ui.dev_name), "%s", argv[optind]);
664
665         ret = exfat_get_blk_dev_info(&ui, &bd);
666         if (ret < 0)
667                 goto out;
668
669         ret = exfat_build_mkfs_info(&bd, &ui);
670         if (ret)
671                 goto close;
672
673         ret = exfat_zero_out_disk(&bd, &ui);
674         if (ret)
675                 goto close;
676
677         ret = make_exfat(&bd, &ui);
678         if (ret)
679                 goto close;
680
681         exfat_info("Synchronizing...\n");
682         ret = fsync(bd.dev_fd);
683 close:
684         close(bd.dev_fd);
685 out:
686         if (!ret)
687                 exfat_info("\nexFAT format complete!\n");
688         else
689                 exfat_info("\nexFAT format fail!\n");
690         return ret;
691 }