]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c
Edited! (#2105)
[Ventoy.git] / LinuxGUI / Ventoy2Disk / Lib / exfat / src / mkfs / mkexfat.c
1 /*
2 mkexfat.c (22.04.12)
3 FS creation engine.
4
5 Free exFAT implementation.
6 Copyright (C) 2011-2018 Andrew Nayenko
7
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.
12
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.
17
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.
21 */
22
23 #include "mkexfat.h"
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 static int check_size(off_t volume_size)
31 {
32 const struct fs_object** pp;
33 off_t position = 0;
34
35 for (pp = objects; *pp; pp++)
36 {
37 position = ROUND_UP(position, (*pp)->get_alignment());
38 position += (*pp)->get_size();
39 }
40
41 if (position > volume_size)
42 {
43 struct exfat_human_bytes vhb;
44
45 exfat_humanize_bytes(volume_size, &vhb);
46 exfat_error("too small device (%"PRIu64" %s)", vhb.value, vhb.unit);
47 return 1;
48 }
49
50 return 0;
51
52 }
53
54 static int erase_object(struct exfat_dev* dev, const void* block,
55 size_t block_size, off_t start, off_t size)
56 {
57 const off_t block_count = DIV_ROUND_UP(size, block_size);
58 off_t i;
59
60 if (exfat_seek(dev, start, SEEK_SET) == (off_t) -1)
61 {
62 exfat_error("seek to 0x%"PRIx64" failed", start);
63 return 1;
64 }
65 for (i = 0; i < size; i += block_size)
66 {
67 if (exfat_write(dev, block, MIN(size - i, block_size)) < 0)
68 {
69 exfat_error("failed to erase block %"PRIu64"/%"PRIu64
70 " at 0x%"PRIx64, i + 1, block_count, start);
71 return 1;
72 }
73 }
74 return 0;
75 }
76
77 static int erase(struct exfat_dev* dev)
78 {
79 const struct fs_object** pp;
80 off_t position = 0;
81 const size_t block_size = 1024 * 1024;
82 void* block = malloc(block_size);
83
84 if (block == NULL)
85 {
86 exfat_error("failed to allocate erase block of %zu bytes", block_size);
87 return 1;
88 }
89 memset(block, 0, block_size);
90
91 for (pp = objects; *pp; pp++)
92 {
93 position = ROUND_UP(position, (*pp)->get_alignment());
94 if (erase_object(dev, block, block_size, position,
95 (*pp)->get_size()) != 0)
96 {
97 free(block);
98 return 1;
99 }
100 position += (*pp)->get_size();
101 }
102
103 free(block);
104 return 0;
105 }
106
107 static int create(struct exfat_dev* dev)
108 {
109 const struct fs_object** pp;
110 off_t position = 0;
111
112 for (pp = objects; *pp; pp++)
113 {
114 position = ROUND_UP(position, (*pp)->get_alignment());
115 if (exfat_seek(dev, position, SEEK_SET) == (off_t) -1)
116 {
117 exfat_error("seek to 0x%"PRIx64" failed", position);
118 return 1;
119 }
120 if ((*pp)->write(dev) != 0)
121 return 1;
122 position += (*pp)->get_size();
123 }
124 return 0;
125 }
126
127 int mkfs(struct exfat_dev* dev, off_t volume_size)
128 {
129 if (check_size(volume_size) != 0)
130 return 1;
131
132 exfat_debug("Creating... ");
133 //fputs("Creating... ", stdout);
134 //fflush(stdout);
135 if (erase(dev) != 0)
136 return 1;
137 if (create(dev) != 0)
138 return 1;
139 //puts("done.");
140
141 //fputs("Flushing... ", stdout);
142 //fflush(stdout);
143 exfat_debug("Flushing... ");
144 if (exfat_fsync(dev) != 0)
145 return 1;
146 //puts("done.");
147
148 return 0;
149 }
150
151 off_t get_position(const struct fs_object* object)
152 {
153 const struct fs_object** pp;
154 off_t position = 0;
155
156 for (pp = objects; *pp; pp++)
157 {
158 position = ROUND_UP(position, (*pp)->get_alignment());
159 if (*pp == object)
160 return position;
161 position += (*pp)->get_size();
162 }
163 exfat_bug("unknown object");
164
165 return 0;
166 }
167