]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c
5 Free exFAT implementation.
6 Copyright (C) 2011-2018 Andrew Nayenko
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <sys/types.h>
30 static int check_size(off_t volume_size
)
32 const struct fs_object
** pp
;
35 for (pp
= objects
; *pp
; pp
++)
37 position
= ROUND_UP(position
, (*pp
)->get_alignment());
38 position
+= (*pp
)->get_size();
41 if (position
> volume_size
)
43 struct exfat_human_bytes vhb
;
45 exfat_humanize_bytes(volume_size
, &vhb
);
46 exfat_error("too small device (%"PRIu64
" %s)", vhb
.value
, vhb
.unit
);
54 static int erase_object(struct exfat_dev
* dev
, const void* block
,
55 size_t block_size
, off_t start
, off_t size
)
57 const off_t block_count
= DIV_ROUND_UP(size
, block_size
);
60 if (exfat_seek(dev
, start
, SEEK_SET
) == (off_t
) -1)
62 exfat_error("seek to 0x%"PRIx64
" failed", start
);
65 for (i
= 0; i
< size
; i
+= block_size
)
67 if (exfat_write(dev
, block
, MIN(size
- i
, block_size
)) < 0)
69 exfat_error("failed to erase block %"PRIu64
"/%"PRIu64
70 " at 0x%"PRIx64
, i
+ 1, block_count
, start
);
77 static int erase(struct exfat_dev
* dev
)
79 const struct fs_object
** pp
;
81 const size_t block_size
= 1024 * 1024;
82 void* block
= malloc(block_size
);
86 exfat_error("failed to allocate erase block of %zu bytes", block_size
);
89 memset(block
, 0, block_size
);
91 for (pp
= objects
; *pp
; pp
++)
93 position
= ROUND_UP(position
, (*pp
)->get_alignment());
94 if (erase_object(dev
, block
, block_size
, position
,
95 (*pp
)->get_size()) != 0)
100 position
+= (*pp
)->get_size();
107 static int create(struct exfat_dev
* dev
)
109 const struct fs_object
** pp
;
112 for (pp
= objects
; *pp
; pp
++)
114 position
= ROUND_UP(position
, (*pp
)->get_alignment());
115 if (exfat_seek(dev
, position
, SEEK_SET
) == (off_t
) -1)
117 exfat_error("seek to 0x%"PRIx64
" failed", position
);
120 if ((*pp
)->write(dev
) != 0)
122 position
+= (*pp
)->get_size();
127 int mkfs(struct exfat_dev
* dev
, off_t volume_size
)
129 if (check_size(volume_size
) != 0)
132 exfat_debug("Creating... ");
133 //fputs("Creating... ", stdout);
137 if (create(dev
) != 0)
141 //fputs("Flushing... ", stdout);
143 exfat_debug("Flushing... ");
144 if (exfat_fsync(dev
) != 0)
151 off_t
get_position(const struct fs_object
* object
)
153 const struct fs_object
** pp
;
156 for (pp
= objects
; *pp
; pp
++)
158 position
= ROUND_UP(position
, (*pp
)->get_alignment());
161 position
+= (*pp
)->get_size();
163 exfat_bug("unknown object");