]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c
3 Creates exFAT file system.
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.
30 #include <sys/types.h>
38 const struct fs_object
* objects
[] =
55 le16_t volume_label
[EXFAT_ENAME_MAX
+ 1];
56 uint32_t volume_serial
;
57 uint64_t first_sector
;
61 extern int g_vtoy_exfat_disk_fd
;
62 extern uint64_t g_vtoy_exfat_part_size
;
64 int get_sector_bits(void)
66 return param
.sector_bits
;
69 int get_spc_bits(void)
71 return param
.spc_bits
;
74 off_t
get_volume_size(void)
76 return param
.volume_size
;
79 const le16_t
* get_volume_label(void)
81 return param
.volume_label
;
84 uint32_t get_volume_serial(void)
86 return param
.volume_serial
;
89 uint64_t get_first_sector(void)
91 return param
.first_sector
;
94 int get_sector_size(void)
96 return 1 << get_sector_bits();
99 int get_cluster_size(void)
101 return get_sector_size() << get_spc_bits();
104 static int setup_spc_bits(int sector_bits
, int user_defined
, off_t volume_size
)
108 if (user_defined
!= -1)
110 off_t cluster_size
= 1 << sector_bits
<< user_defined
;
111 if (volume_size
/ cluster_size
> EXFAT_LAST_DATA_CLUSTER
)
113 struct exfat_human_bytes chb
, vhb
;
115 exfat_humanize_bytes(cluster_size
, &chb
);
116 exfat_humanize_bytes(volume_size
, &vhb
);
117 exfat_error("cluster size %"PRIu64
" %s is too small for "
118 "%"PRIu64
" %s volume, try -s %d",
121 1 << setup_spc_bits(sector_bits
, -1, volume_size
));
127 if (volume_size
< 256ull * 1024 * 1024)
128 return MAX(0, 12 - sector_bits
); /* 4 KB */
129 if (volume_size
< 32ull * 1024 * 1024 * 1024)
130 return MAX(0, 15 - sector_bits
); /* 32 KB */
132 for (i
= 17; ; i
++) /* 128 KB or more */
133 if (DIV_ROUND_UP(volume_size
, 1 << i
) <= EXFAT_LAST_DATA_CLUSTER
)
134 return MAX(0, i
- sector_bits
);
137 static int setup_volume_label(le16_t label
[EXFAT_ENAME_MAX
+ 1], const char* s
)
139 memset(label
, 0, (EXFAT_ENAME_MAX
+ 1) * sizeof(le16_t
));
142 return utf8_to_utf16(label
, s
, EXFAT_ENAME_MAX
+ 1, strlen(s
));
145 static uint32_t setup_volume_serial(uint32_t user_defined
)
149 if (user_defined
!= 0)
152 if (gettimeofday(&now
, NULL
) != 0)
154 exfat_error("failed to form volume id");
157 return (now
.tv_sec
<< 20) | now
.tv_usec
;
160 static int setup(struct exfat_dev
* dev
, int sector_bits
, int spc_bits
,
161 const char* volume_label
, uint32_t volume_serial
,
162 uint64_t first_sector
)
164 param
.sector_bits
= sector_bits
;
165 param
.first_sector
= first_sector
;
166 param
.volume_size
= exfat_get_size(dev
);
168 param
.spc_bits
= setup_spc_bits(sector_bits
, spc_bits
, param
.volume_size
);
169 if (param
.spc_bits
== -1)
172 if (setup_volume_label(param
.volume_label
, volume_label
) != 0)
175 param
.volume_serial
= setup_volume_serial(volume_serial
);
176 if (param
.volume_serial
== 0)
179 return mkfs(dev
, param
.volume_size
);
182 static int logarithm2(int n
)
186 for (i
= 0; i
< sizeof(int) * CHAR_BIT
- 1; i
++)
192 static void usage(const char* prog
)
194 fprintf(stderr
, "Usage: %s [-i volume-id] [-n label] "
195 "[-p partition-first-sector] "
196 "[-s sectors-per-cluster] [-V] <device>\n", prog
);
200 int mkexfat_main(const char *devpath
, int fd
, uint64_t part_sector_count
)
203 uint32_t volume_serial
= 0;
204 uint64_t first_sector
= 0;
205 struct exfat_dev
* dev
;
208 while ((opt
= getopt(argc
, argv
, "i:n:p:s:V")) != -1)
213 volume_serial
= strtol(optarg
, NULL
, 16);
216 volume_label
= optarg
;
219 first_sector
= strtoll(optarg
, NULL
, 10);
222 spc_bits
= logarithm2(atoi(optarg
));
225 exfat_error("invalid option value: '%s'", optarg
);
230 puts("Copyright (C) 2011-2018 Andrew Nayenko");
240 * DiskSize > 32GB Cluster Size use 128KB
241 * DiskSize < 32GB Cluster Size use 32KB
243 if ((part_sector_count
/ 2097152) > 32)
245 spc_bits
= logarithm2(256);
249 spc_bits
= logarithm2(64);
252 g_vtoy_exfat_disk_fd
= fd
;
253 g_vtoy_exfat_part_size
= part_sector_count
* 512;
255 dev
= exfat_open(devpath
, EXFAT_MODE_RW
);
258 if (setup(dev
, 9, spc_bits
, "Ventoy", volume_serial
, first_sector
) != 0)
263 if (exfat_close(dev
) != 0)