external/exfat
Revisión | bbf4594405ceef9defeba24a596b46d26f73b512 (tree) |
---|---|
Tiempo | 2021-07-06 17:30:40 |
Autor | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge branch 'master' of git://github.com/relan/exfat into pie-x86
@@ -0,0 +1,56 @@ | ||
1 | +# | |
2 | +# .travis.yml (29.02.20) | |
3 | +# Travis Contiguous Integration configuration. | |
4 | +# | |
5 | +# Free exFAT implementation. | |
6 | +# Copyright (C) 2010-2020 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 | +--- | |
24 | +language: c | |
25 | + | |
26 | +jobs: | |
27 | + include: | |
28 | + - os: linux | |
29 | + dist: bionic | |
30 | + arch: amd64 | |
31 | + - os: linux | |
32 | + dist: bionic | |
33 | + arch: ppc64le | |
34 | + - os: linux | |
35 | + dist: bionic | |
36 | + arch: s390x | |
37 | + - os: osx | |
38 | + osx_image: xcode12.2 | |
39 | + | |
40 | +addons: | |
41 | + apt: | |
42 | + packages: | |
43 | + - libfuse-dev | |
44 | + homebrew: | |
45 | + update: true | |
46 | + casks: | |
47 | + - osxfuse | |
48 | + | |
49 | +script: | |
50 | + - autoreconf --install | |
51 | + - ./configure CFLAGS='-Wall -Wextra' | |
52 | + - make -k | |
53 | + - dd if=/dev/zero of=foo.img bs=1048576 count=1 | |
54 | + - mkfs/mkexfatfs -i 12345678 foo.img | |
55 | + - fsck/exfatfsck foo.img | |
56 | + - echo 'f1b3a11f781533f5b69086596be38367d0ebfb77 foo.img' | shasum -c |
@@ -132,6 +132,7 @@ static void fsck(struct exfat* ef, const char* spec, const char* options) | ||
132 | 132 | } |
133 | 133 | |
134 | 134 | exfat_print_info(ef->sb, exfat_count_free_clusters(ef)); |
135 | + exfat_soil_super_block(ef); | |
135 | 136 | dirck(ef, ""); |
136 | 137 | exfat_unmount(ef); |
137 | 138 |
@@ -98,7 +98,8 @@ static int fuse_exfat_truncate(const char* path, off_t size) | ||
98 | 98 | } |
99 | 99 | |
100 | 100 | static int fuse_exfat_readdir(const char* path, void* buffer, |
101 | - fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi) | |
101 | + fuse_fill_dir_t filler, UNUSED off_t offset, | |
102 | + UNUSED struct fuse_file_info* fi) | |
102 | 103 | { |
103 | 104 | struct exfat_node* parent; |
104 | 105 | struct exfat_node* node; |
@@ -158,7 +159,7 @@ static int fuse_exfat_open(const char* path, struct fuse_file_info* fi) | ||
158 | 159 | return 0; |
159 | 160 | } |
160 | 161 | |
161 | -static int fuse_exfat_create(const char* path, mode_t mode, | |
162 | +static int fuse_exfat_create(const char* path, UNUSED mode_t mode, | |
162 | 163 | struct fuse_file_info* fi) |
163 | 164 | { |
164 | 165 | struct exfat_node* node; |
@@ -176,7 +177,8 @@ static int fuse_exfat_create(const char* path, mode_t mode, | ||
176 | 177 | return 0; |
177 | 178 | } |
178 | 179 | |
179 | -static int fuse_exfat_release(const char* path, struct fuse_file_info* fi) | |
180 | +static int fuse_exfat_release(UNUSED const char* path, | |
181 | + struct fuse_file_info* fi) | |
180 | 182 | { |
181 | 183 | /* |
182 | 184 | This handler is called by FUSE on close() syscall. If the FUSE |
@@ -190,7 +192,7 @@ static int fuse_exfat_release(const char* path, struct fuse_file_info* fi) | ||
190 | 192 | return 0; /* FUSE ignores this return value */ |
191 | 193 | } |
192 | 194 | |
193 | -static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi) | |
195 | +static int fuse_exfat_flush(UNUSED const char* path, struct fuse_file_info* fi) | |
194 | 196 | { |
195 | 197 | /* |
196 | 198 | This handler may be called by FUSE on close() syscall. FUSE also deals |
@@ -202,8 +204,8 @@ static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi) | ||
202 | 204 | return exfat_flush_node(&ef, get_node(fi)); |
203 | 205 | } |
204 | 206 | |
205 | -static int fuse_exfat_fsync(const char* path, int datasync, | |
206 | - struct fuse_file_info *fi) | |
207 | +static int fuse_exfat_fsync(UNUSED const char* path, UNUSED int datasync, | |
208 | + UNUSED struct fuse_file_info *fi) | |
207 | 209 | { |
208 | 210 | int rc; |
209 | 211 |
@@ -217,15 +219,15 @@ static int fuse_exfat_fsync(const char* path, int datasync, | ||
217 | 219 | return exfat_fsync(ef.dev); |
218 | 220 | } |
219 | 221 | |
220 | -static int fuse_exfat_read(const char* path, char* buffer, size_t size, | |
221 | - off_t offset, struct fuse_file_info* fi) | |
222 | +static int fuse_exfat_read(UNUSED const char* path, char* buffer, | |
223 | + size_t size, off_t offset, struct fuse_file_info* fi) | |
222 | 224 | { |
223 | 225 | exfat_debug("[%s] %s (%zu bytes)", __func__, path, size); |
224 | 226 | return exfat_generic_pread(&ef, get_node(fi), buffer, size, offset); |
225 | 227 | } |
226 | 228 | |
227 | -static int fuse_exfat_write(const char* path, const char* buffer, size_t size, | |
228 | - off_t offset, struct fuse_file_info* fi) | |
229 | +static int fuse_exfat_write(UNUSED const char* path, const char* buffer, | |
230 | + size_t size, off_t offset, struct fuse_file_info* fi) | |
229 | 231 | { |
230 | 232 | exfat_debug("[%s] %s (%zu bytes)", __func__, path, size); |
231 | 233 | return exfat_generic_pwrite(&ef, get_node(fi), buffer, size, offset); |
@@ -267,13 +269,14 @@ static int fuse_exfat_rmdir(const char* path) | ||
267 | 269 | return exfat_cleanup_node(&ef, node); |
268 | 270 | } |
269 | 271 | |
270 | -static int fuse_exfat_mknod(const char* path, mode_t mode, dev_t dev) | |
272 | +static int fuse_exfat_mknod(const char* path, UNUSED mode_t mode, | |
273 | + UNUSED dev_t dev) | |
271 | 274 | { |
272 | 275 | exfat_debug("[%s] %s 0%ho", __func__, path, mode); |
273 | 276 | return exfat_mknod(&ef, path); |
274 | 277 | } |
275 | 278 | |
276 | -static int fuse_exfat_mkdir(const char* path, mode_t mode) | |
279 | +static int fuse_exfat_mkdir(const char* path, UNUSED mode_t mode) | |
277 | 280 | { |
278 | 281 | exfat_debug("[%s] %s 0%ho", __func__, path, mode); |
279 | 282 | return exfat_mkdir(&ef, path); |
@@ -302,7 +305,7 @@ static int fuse_exfat_utimens(const char* path, const struct timespec tv[2]) | ||
302 | 305 | return rc; |
303 | 306 | } |
304 | 307 | |
305 | -static int fuse_exfat_chmod(const char* path, mode_t mode) | |
308 | +static int fuse_exfat_chmod(UNUSED const char* path, mode_t mode) | |
306 | 309 | { |
307 | 310 | const mode_t VALID_MODE_MASK = S_IFREG | S_IFDIR | |
308 | 311 | S_IRWXU | S_IRWXG | S_IRWXO; |
@@ -313,7 +316,7 @@ static int fuse_exfat_chmod(const char* path, mode_t mode) | ||
313 | 316 | return 0; |
314 | 317 | } |
315 | 318 | |
316 | -static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid) | |
319 | +static int fuse_exfat_chown(UNUSED const char* path, uid_t uid, gid_t gid) | |
317 | 320 | { |
318 | 321 | exfat_debug("[%s] %s %u:%u", __func__, path, uid, gid); |
319 | 322 | if (uid != ef.uid || gid != ef.gid) |
@@ -321,7 +324,7 @@ static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid) | ||
321 | 324 | return 0; |
322 | 325 | } |
323 | 326 | |
324 | -static int fuse_exfat_statfs(const char* path, struct statvfs* sfs) | |
327 | +static int fuse_exfat_statfs(UNUSED const char* path, struct statvfs* sfs) | |
325 | 328 | { |
326 | 329 | exfat_debug("[%s]", __func__); |
327 | 330 |
@@ -351,10 +354,14 @@ static void* fuse_exfat_init(struct fuse_conn_info* fci) | ||
351 | 354 | #ifdef FUSE_CAP_BIG_WRITES |
352 | 355 | fci->want |= FUSE_CAP_BIG_WRITES; |
353 | 356 | #endif |
357 | + | |
358 | + /* mark super block as dirty; failure isn't a big deal */ | |
359 | + exfat_soil_super_block(&ef); | |
360 | + | |
354 | 361 | return NULL; |
355 | 362 | } |
356 | 363 | |
357 | -static void fuse_exfat_destroy(void* unused) | |
364 | +static void fuse_exfat_destroy(UNUSED void* unused) | |
358 | 365 | { |
359 | 366 | exfat_debug("[%s]", __func__); |
360 | 367 | exfat_unmount(&ef); |
@@ -122,7 +122,7 @@ static cluster_t find_bit_and_set(bitmap_t* bitmap, size_t start, size_t end) | ||
122 | 122 | |
123 | 123 | for (i = start_index; i < end_index; i++) |
124 | 124 | { |
125 | - if (bitmap[i] == ~((bitmap_t) 0)) | |
125 | + if (bitmap[i] == (bitmap_t) ~((bitmap_t) 0)) | |
126 | 126 | continue; |
127 | 127 | start_bitindex = MAX(i * sizeof(bitmap_t) * 8, start); |
128 | 128 | end_bitindex = MIN((i + 1) * sizeof(bitmap_t) * 8, end); |
@@ -280,7 +280,7 @@ static int grow_file(struct exfat* ef, struct exfat_node* node, | ||
280 | 280 | shrink_file(ef, node, current + allocated, allocated); |
281 | 281 | return -ENOSPC; |
282 | 282 | } |
283 | - if (next != previous - 1 && node->is_contiguous) | |
283 | + if (next != previous + 1 && node->is_contiguous) | |
284 | 284 | { |
285 | 285 | /* it's a pity, but we are not able to keep the file contiguous |
286 | 286 | anymore */ |
@@ -33,6 +33,7 @@ | ||
33 | 33 | #define PRINTF __attribute__((format(printf, 1, 2))) |
34 | 34 | #define NORETURN __attribute__((noreturn)) |
35 | 35 | #define PACKED __attribute__((packed)) |
36 | +#define UNUSED __attribute__((unused)) | |
36 | 37 | #if __has_extension(c_static_assert) |
37 | 38 | #define USE_C11_STATIC_ASSERT |
38 | 39 | #endif |
@@ -42,6 +43,7 @@ | ||
42 | 43 | #define PRINTF __attribute__((format(printf, 1, 2))) |
43 | 44 | #define NORETURN __attribute__((noreturn)) |
44 | 45 | #define PACKED __attribute__((packed)) |
46 | +#define UNUSED __attribute__((unused)) | |
45 | 47 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) |
46 | 48 | #define USE_C11_STATIC_ASSERT |
47 | 49 | #endif |
@@ -51,6 +53,7 @@ | ||
51 | 53 | #define PRINTF |
52 | 54 | #define NORETURN |
53 | 55 | #define PACKED |
56 | +#define UNUSED | |
54 | 57 | |
55 | 58 | #endif |
56 | 59 |
@@ -201,12 +201,13 @@ le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name, | ||
201 | 201 | void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb); |
202 | 202 | void exfat_print_info(const struct exfat_super_block* sb, |
203 | 203 | uint32_t free_clusters); |
204 | +bool exfat_match_option(const char* options, const char* option_name); | |
204 | 205 | |
205 | -int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, | |
206 | +int exfat_utf16_to_utf8(char* output, const le16_t* input, size_t outsize, | |
206 | 207 | size_t insize); |
207 | -int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, | |
208 | +int exfat_utf8_to_utf16(le16_t* output, const char* input, size_t outsize, | |
208 | 209 | size_t insize); |
209 | -size_t utf16_length(const le16_t* str); | |
210 | +size_t exfat_utf16_length(const le16_t* str); | |
210 | 211 | |
211 | 212 | struct exfat_node* exfat_get_node(struct exfat_node* node); |
212 | 213 | void exfat_put_node(struct exfat* ef, struct exfat_node* node); |
@@ -225,6 +226,7 @@ void exfat_update_mtime(struct exfat_node* node); | ||
225 | 226 | const char* exfat_get_label(struct exfat* ef); |
226 | 227 | int exfat_set_label(struct exfat* ef, const char* label); |
227 | 228 | |
229 | +int exfat_soil_super_block(const struct exfat* ef); | |
228 | 230 | int exfat_mount(struct exfat* ef, const char* spec, const char* options); |
229 | 231 | void exfat_unmount(struct exfat* ef); |
230 | 232 |
@@ -373,24 +373,27 @@ ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, | ||
373 | 373 | ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, |
374 | 374 | void* buffer, size_t size, off_t offset) |
375 | 375 | { |
376 | + uint64_t newsize = offset; | |
376 | 377 | cluster_t cluster; |
377 | 378 | char* bufp = buffer; |
378 | 379 | off_t lsize, loffset, remainder; |
379 | 380 | |
380 | - if (offset >= node->size) | |
381 | + if (offset < 0) | |
382 | + return -EINVAL; | |
383 | + if (newsize >= node->size) | |
381 | 384 | return 0; |
382 | 385 | if (size == 0) |
383 | 386 | return 0; |
384 | 387 | |
385 | - cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb)); | |
388 | + cluster = exfat_advance_cluster(ef, node, newsize / CLUSTER_SIZE(*ef->sb)); | |
386 | 389 | if (CLUSTER_INVALID(*ef->sb, cluster)) |
387 | 390 | { |
388 | 391 | exfat_error("invalid cluster 0x%x while reading", cluster); |
389 | 392 | return -EIO; |
390 | 393 | } |
391 | 394 | |
392 | - loffset = offset % CLUSTER_SIZE(*ef->sb); | |
393 | - remainder = MIN(size, node->size - offset); | |
395 | + loffset = newsize % CLUSTER_SIZE(*ef->sb); | |
396 | + remainder = MIN(size, node->size - newsize); | |
394 | 397 | while (remainder > 0) |
395 | 398 | { |
396 | 399 | if (CLUSTER_INVALID(*ef->sb, cluster)) |
@@ -412,40 +415,43 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, | ||
412 | 415 | } |
413 | 416 | if (!(node->attrib & EXFAT_ATTRIB_DIR) && !ef->ro && !ef->noatime) |
414 | 417 | exfat_update_atime(node); |
415 | - return MIN(size, node->size - offset) - remainder; | |
418 | + return MIN(size, node->size - newsize) - remainder; | |
416 | 419 | } |
417 | 420 | |
418 | 421 | ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, |
419 | 422 | const void* buffer, size_t size, off_t offset) |
420 | 423 | { |
424 | + uint64_t newsize = offset; | |
421 | 425 | int rc; |
422 | 426 | cluster_t cluster; |
423 | 427 | const char* bufp = buffer; |
424 | 428 | off_t lsize, loffset, remainder; |
425 | 429 | |
426 | - if (offset > node->size) | |
430 | + if (offset < 0) | |
431 | + return -EINVAL; | |
432 | + if (newsize > node->size) | |
427 | 433 | { |
428 | - rc = exfat_truncate(ef, node, offset, true); | |
434 | + rc = exfat_truncate(ef, node, newsize, true); | |
429 | 435 | if (rc != 0) |
430 | 436 | return rc; |
431 | 437 | } |
432 | - if (offset + size > node->size) | |
438 | + if (newsize + size > node->size) | |
433 | 439 | { |
434 | - rc = exfat_truncate(ef, node, offset + size, false); | |
440 | + rc = exfat_truncate(ef, node, newsize + size, false); | |
435 | 441 | if (rc != 0) |
436 | 442 | return rc; |
437 | 443 | } |
438 | 444 | if (size == 0) |
439 | 445 | return 0; |
440 | 446 | |
441 | - cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb)); | |
447 | + cluster = exfat_advance_cluster(ef, node, newsize / CLUSTER_SIZE(*ef->sb)); | |
442 | 448 | if (CLUSTER_INVALID(*ef->sb, cluster)) |
443 | 449 | { |
444 | 450 | exfat_error("invalid cluster 0x%x while writing", cluster); |
445 | 451 | return -EIO; |
446 | 452 | } |
447 | 453 | |
448 | - loffset = offset % CLUSTER_SIZE(*ef->sb); | |
454 | + loffset = newsize % CLUSTER_SIZE(*ef->sb); | |
449 | 455 | remainder = size; |
450 | 456 | while (remainder > 0) |
451 | 457 | { |
@@ -86,7 +86,7 @@ static int lookup_name(struct exfat* ef, struct exfat_node* parent, | ||
86 | 86 | |
87 | 87 | *node = NULL; |
88 | 88 | |
89 | - rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n); | |
89 | + rc = exfat_utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n); | |
90 | 90 | if (rc != 0) |
91 | 91 | return rc; |
92 | 92 |
@@ -194,7 +194,7 @@ int exfat_split(struct exfat* ef, struct exfat_node** parent, | ||
194 | 194 | exfat_put_node(ef, *parent); |
195 | 195 | return -ENOENT; |
196 | 196 | } |
197 | - rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n); | |
197 | + rc = exfat_utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n); | |
198 | 198 | if (rc != 0) |
199 | 199 | { |
200 | 200 | exfat_put_node(ef, *parent); |
@@ -79,18 +79,6 @@ static int get_int_option(const char* options, const char* option_name, | ||
79 | 79 | return strtol(p, NULL, base); |
80 | 80 | } |
81 | 81 | |
82 | -static bool match_option(const char* options, const char* option_name) | |
83 | -{ | |
84 | - const char* p; | |
85 | - size_t length = strlen(option_name); | |
86 | - | |
87 | - for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name)) | |
88 | - if ((p == options || p[-1] == ',') && | |
89 | - (p[length] == ',' || p[length] == '\0')) | |
90 | - return true; | |
91 | - return false; | |
92 | -} | |
93 | - | |
94 | 82 | static void parse_options(struct exfat* ef, const char* options) |
95 | 83 | { |
96 | 84 | int opt_umask; |
@@ -102,7 +90,7 @@ static void parse_options(struct exfat* ef, const char* options) | ||
102 | 90 | ef->uid = get_int_option(options, "uid", 10, geteuid()); |
103 | 91 | ef->gid = get_int_option(options, "gid", 10, getegid()); |
104 | 92 | |
105 | - ef->noatime = match_option(options, "noatime"); | |
93 | + ef->noatime = exfat_match_option(options, "noatime"); | |
106 | 94 | |
107 | 95 | switch (get_int_option(options, "repair", 10, 0)) |
108 | 96 | { |
@@ -122,7 +110,7 @@ static bool verify_vbr_checksum(const struct exfat* ef, void* sector) | ||
122 | 110 | { |
123 | 111 | off_t sector_size = SECTOR_SIZE(*ef->sb); |
124 | 112 | uint32_t vbr_checksum; |
125 | - int i; | |
113 | + size_t i; | |
126 | 114 | |
127 | 115 | if (exfat_pread(ef->dev, sector, sector_size, 0) < 0) |
128 | 116 | { |
@@ -166,11 +154,8 @@ static int commit_super_block(const struct exfat* ef) | ||
166 | 154 | return exfat_fsync(ef->dev); |
167 | 155 | } |
168 | 156 | |
169 | -static int prepare_super_block(const struct exfat* ef) | |
157 | +int exfat_soil_super_block(const struct exfat* ef) | |
170 | 158 | { |
171 | - if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED) | |
172 | - exfat_warn("volume was not unmounted cleanly"); | |
173 | - | |
174 | 159 | if (ef->ro) |
175 | 160 | return 0; |
176 | 161 |
@@ -205,9 +190,9 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options) | ||
205 | 190 | |
206 | 191 | parse_options(ef, options); |
207 | 192 | |
208 | - if (match_option(options, "ro")) | |
193 | + if (exfat_match_option(options, "ro")) | |
209 | 194 | mode = EXFAT_MODE_RO; |
210 | - else if (match_option(options, "ro_fallback")) | |
195 | + else if (exfat_match_option(options, "ro_fallback")) | |
211 | 196 | mode = EXFAT_MODE_ANY; |
212 | 197 | else |
213 | 198 | mode = EXFAT_MODE_RW; |
@@ -286,7 +271,7 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options) | ||
286 | 271 | return -EIO; |
287 | 272 | } |
288 | 273 | if (le64_to_cpu(ef->sb->sector_count) * SECTOR_SIZE(*ef->sb) > |
289 | - exfat_get_size(ef->dev)) | |
274 | + (uint64_t) exfat_get_size(ef->dev)) | |
290 | 275 | { |
291 | 276 | /* this can cause I/O errors later but we don't fail mounting to let |
292 | 277 | user rescue data */ |
@@ -305,6 +290,8 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options) | ||
305 | 290 | exfat_free(ef); |
306 | 291 | return -EIO; |
307 | 292 | } |
293 | + if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED) | |
294 | + exfat_warn("volume was not unmounted cleanly"); | |
308 | 295 | |
309 | 296 | ef->root = malloc(sizeof(struct exfat_node)); |
310 | 297 | if (ef->root == NULL) |
@@ -344,9 +331,6 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options) | ||
344 | 331 | goto error; |
345 | 332 | } |
346 | 333 | |
347 | - if (prepare_super_block(ef) != 0) | |
348 | - goto error; | |
349 | - | |
350 | 334 | return 0; |
351 | 335 | |
352 | 336 | error: |
@@ -87,7 +87,7 @@ static int read_entries(struct exfat* ef, struct exfat_node* dir, | ||
87 | 87 | |
88 | 88 | size = exfat_generic_pread(ef, dir, entries, |
89 | 89 | sizeof(struct exfat_entry[n]), offset); |
90 | - if (size == sizeof(struct exfat_entry[n])) | |
90 | + if (size == (ssize_t) sizeof(struct exfat_entry) * n) | |
91 | 91 | return 0; /* success */ |
92 | 92 | if (size == 0) |
93 | 93 | return -ENOENT; |
@@ -108,7 +108,7 @@ static int write_entries(struct exfat* ef, struct exfat_node* dir, | ||
108 | 108 | |
109 | 109 | size = exfat_generic_pwrite(ef, dir, entries, |
110 | 110 | sizeof(struct exfat_entry[n]), offset); |
111 | - if (size == sizeof(struct exfat_entry[n])) | |
111 | + if (size == (ssize_t) sizeof(struct exfat_entry) * n) | |
112 | 112 | return 0; /* success */ |
113 | 113 | if (size < 0) |
114 | 114 | return -EIO; |
@@ -396,6 +396,7 @@ static int readdir(struct exfat* ef, struct exfat_node* parent, | ||
396 | 396 | const struct exfat_entry_label* label; |
397 | 397 | uint64_t upcase_size = 0; |
398 | 398 | le16_t* upcase_comp = NULL; |
399 | + le16_t label_name[EXFAT_ENAME_MAX]; | |
399 | 400 | |
400 | 401 | for (;;) |
401 | 402 | { |
@@ -508,7 +509,10 @@ static int readdir(struct exfat* ef, struct exfat_node* parent, | ||
508 | 509 | exfat_error("too long label (%hhu chars)", label->length); |
509 | 510 | return -EIO; |
510 | 511 | } |
511 | - if (utf16_to_utf8(ef->label, label->name, | |
512 | + /* copy to a temporary buffer to avoid unaligned access to a | |
513 | + packed member */ | |
514 | + memcpy(label_name, label->name, sizeof(label_name)); | |
515 | + if (exfat_utf16_to_utf8(ef->label, label_name, | |
512 | 516 | sizeof(ef->label), EXFAT_ENAME_MAX) != 0) |
513 | 517 | return -EIO; |
514 | 518 | break; |
@@ -628,6 +632,7 @@ int exfat_flush_node(struct exfat* ef, struct exfat_node* node) | ||
628 | 632 | struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; |
629 | 633 | struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; |
630 | 634 | int rc; |
635 | + le16_t edate, etime; | |
631 | 636 | |
632 | 637 | if (!node->is_dirty) |
633 | 638 | return 0; /* no need to flush */ |
@@ -646,10 +651,14 @@ int exfat_flush_node(struct exfat* ef, struct exfat_node* node) | ||
646 | 651 | return -EIO; |
647 | 652 | |
648 | 653 | meta1->attrib = cpu_to_le16(node->attrib); |
649 | - exfat_unix2exfat(node->mtime, &meta1->mdate, &meta1->mtime, | |
654 | + exfat_unix2exfat(node->mtime, &edate, &etime, | |
650 | 655 | &meta1->mtime_cs, &meta1->mtime_tzo); |
651 | - exfat_unix2exfat(node->atime, &meta1->adate, &meta1->atime, | |
656 | + meta1->mdate = edate; | |
657 | + meta1->mtime = etime; | |
658 | + exfat_unix2exfat(node->atime, &edate, &etime, | |
652 | 659 | NULL, &meta1->atime_tzo); |
660 | + meta1->adate = edate; | |
661 | + meta1->atime = etime; | |
653 | 662 | meta2->size = meta2->valid_size = cpu_to_le64(node->size); |
654 | 663 | meta2->start_cluster = cpu_to_le32(node->start_cluster); |
655 | 664 | meta2->flags = EXFAT_FLAG_ALWAYS1; |
@@ -732,7 +741,7 @@ static int shrink_directory(struct exfat* ef, struct exfat_node* dir, | ||
732 | 741 | /* two subentries with meta info */ |
733 | 742 | entries += 2; |
734 | 743 | /* subentries with file name */ |
735 | - entries += DIV_ROUND_UP(utf16_length(last_node->name), | |
744 | + entries += DIV_ROUND_UP(exfat_utf16_length(last_node->name), | |
736 | 745 | EXFAT_ENAME_MAX); |
737 | 746 | } |
738 | 747 |
@@ -800,7 +809,7 @@ static int check_slot(struct exfat* ef, struct exfat_node* dir, off_t offset, | ||
800 | 809 | { |
801 | 810 | struct exfat_entry entries[n]; |
802 | 811 | int rc; |
803 | - size_t i; | |
812 | + int i; | |
804 | 813 | |
805 | 814 | /* Root directory contains entries, that don't have any nodes associated |
806 | 815 | with them (clusters bitmap, upper case table, label). We need to be |
@@ -838,7 +847,7 @@ static int find_slot(struct exfat* ef, struct exfat_node* dir, | ||
838 | 847 | return -ENOMEM; |
839 | 848 | } |
840 | 849 | for (p = dir->child; p != NULL; p = p->next) |
841 | - for (i = 0; i < 1 + p->continuations; i++) | |
850 | + for (i = 0; i < 1u + p->continuations; i++) | |
842 | 851 | BMAP_SET(dmap, p->entry_offset / sizeof(struct exfat_entry) + i); |
843 | 852 | |
844 | 853 | /* find a slot in the directory entries bitmap */ |
@@ -883,23 +892,24 @@ static int commit_entry(struct exfat* ef, struct exfat_node* dir, | ||
883 | 892 | const le16_t* name, off_t offset, uint16_t attrib) |
884 | 893 | { |
885 | 894 | struct exfat_node* node; |
886 | - const size_t name_length = utf16_length(name); | |
895 | + const size_t name_length = exfat_utf16_length(name); | |
887 | 896 | const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX); |
888 | 897 | struct exfat_entry entries[2 + name_entries]; |
889 | 898 | struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; |
890 | 899 | struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; |
891 | 900 | int i; |
892 | 901 | int rc; |
902 | + le16_t edate, etime; | |
893 | 903 | |
894 | 904 | memset(entries, 0, sizeof(struct exfat_entry[2])); |
895 | 905 | |
896 | 906 | meta1->type = EXFAT_ENTRY_FILE; |
897 | 907 | meta1->continuations = 1 + name_entries; |
898 | 908 | meta1->attrib = cpu_to_le16(attrib); |
899 | - exfat_unix2exfat(time(NULL), &meta1->crdate, &meta1->crtime, | |
909 | + exfat_unix2exfat(time(NULL), &edate, &etime, | |
900 | 910 | &meta1->crtime_cs, &meta1->crtime_tzo); |
901 | - meta1->adate = meta1->mdate = meta1->crdate; | |
902 | - meta1->atime = meta1->mtime = meta1->crtime; | |
911 | + meta1->adate = meta1->mdate = meta1->crdate = edate; | |
912 | + meta1->atime = meta1->mtime = meta1->crtime = etime; | |
903 | 913 | meta1->mtime_cs = meta1->crtime_cs; /* there is no atime_cs */ |
904 | 914 | meta1->atime_tzo = meta1->mtime_tzo = meta1->crtime_tzo; |
905 | 915 |
@@ -956,7 +966,7 @@ static int create(struct exfat* ef, const char* path, uint16_t attrib) | ||
956 | 966 | } |
957 | 967 | |
958 | 968 | rc = find_slot(ef, dir, &offset, |
959 | - 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX)); | |
969 | + 2 + DIV_ROUND_UP(exfat_utf16_length(name), EXFAT_ENAME_MAX)); | |
960 | 970 | if (rc != 0) |
961 | 971 | { |
962 | 972 | exfat_put_node(ef, dir); |
@@ -1012,7 +1022,7 @@ int exfat_mkdir(struct exfat* ef, const char* path) | ||
1012 | 1022 | static int rename_entry(struct exfat* ef, struct exfat_node* dir, |
1013 | 1023 | struct exfat_node* node, const le16_t* name, off_t new_offset) |
1014 | 1024 | { |
1015 | - const size_t name_length = utf16_length(name); | |
1025 | + const size_t name_length = exfat_utf16_length(name); | |
1016 | 1026 | const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX); |
1017 | 1027 | struct exfat_entry entries[2 + name_entries]; |
1018 | 1028 | struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; |
@@ -1135,7 +1145,7 @@ int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path) | ||
1135 | 1145 | } |
1136 | 1146 | |
1137 | 1147 | rc = find_slot(ef, dir, &offset, |
1138 | - 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX)); | |
1148 | + 2 + DIV_ROUND_UP(exfat_utf16_length(name), EXFAT_ENAME_MAX)); | |
1139 | 1149 | if (rc != 0) |
1140 | 1150 | { |
1141 | 1151 | exfat_put_node(ef, dir); |
@@ -1204,7 +1214,8 @@ int exfat_set_label(struct exfat* ef, const char* label) | ||
1204 | 1214 | struct exfat_entry_label entry; |
1205 | 1215 | |
1206 | 1216 | memset(label_utf16, 0, sizeof(label_utf16)); |
1207 | - rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1, strlen(label)); | |
1217 | + rc = exfat_utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1, | |
1218 | + strlen(label)); | |
1208 | 1219 | if (rc != 0) |
1209 | 1220 | return rc; |
1210 | 1221 |
@@ -1215,7 +1226,7 @@ int exfat_set_label(struct exfat* ef, const char* label) | ||
1215 | 1226 | return rc; |
1216 | 1227 | |
1217 | 1228 | entry.type = EXFAT_ENTRY_LABEL; |
1218 | - entry.length = utf16_length(label_utf16); | |
1229 | + entry.length = exfat_utf16_length(label_utf16); | |
1219 | 1230 | memcpy(entry.name, label_utf16, sizeof(entry.name)); |
1220 | 1231 | if (entry.length == 0) |
1221 | 1232 | entry.type ^= EXFAT_ENTRY_VALID; |
@@ -56,6 +56,16 @@ | ||
56 | 56 | #define EXFAT_LITTLE_ENDIAN _LITTLE_ENDIAN |
57 | 57 | #define EXFAT_BIG_ENDIAN _BIG_ENDIAN |
58 | 58 | |
59 | +#elif defined(__sun) | |
60 | + | |
61 | +#include <endian.h> | |
62 | +#define exfat_bswap16(x) bswap_16(x) | |
63 | +#define exfat_bswap32(x) bswap_32(x) | |
64 | +#define exfat_bswap64(x) bswap_64(x) | |
65 | +#define EXFAT_BYTE_ORDER __BYTE_ORDER | |
66 | +#define EXFAT_LITTLE_ENDIAN __LITTLE_ENDIAN | |
67 | +#define EXFAT_BIG_ENDIAN __BIG_ENDIAN | |
68 | + | |
59 | 69 | #else |
60 | 70 | #error Unknown platform |
61 | 71 | #endif |
@@ -77,7 +77,7 @@ bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector, | ||
77 | 77 | return true; |
78 | 78 | } |
79 | 79 | |
80 | -bool exfat_fix_invalid_node_checksum(const struct exfat* ef, | |
80 | +bool exfat_fix_invalid_node_checksum(UNUSED const struct exfat* ef, | |
81 | 81 | struct exfat_node* node) |
82 | 82 | { |
83 | 83 | /* checksum will be rewritten by exfat_flush_node() */ |
@@ -101,23 +101,25 @@ static const le16_t* utf16_to_wchar(const le16_t* input, wchar_t* wc, | ||
101 | 101 | } |
102 | 102 | } |
103 | 103 | |
104 | -int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, | |
104 | +int exfat_utf16_to_utf8(char* output, const le16_t* input, size_t outsize, | |
105 | 105 | size_t insize) |
106 | 106 | { |
107 | - const le16_t* inp = input; | |
108 | - char* outp = output; | |
107 | + const le16_t* iptr = input; | |
108 | + const le16_t* iend = input + insize; | |
109 | + char* optr = output; | |
110 | + const char* oend = output + outsize; | |
109 | 111 | wchar_t wc; |
110 | 112 | |
111 | - while (inp - input < insize) | |
113 | + while (iptr < iend) | |
112 | 114 | { |
113 | - inp = utf16_to_wchar(inp, &wc, insize - (inp - input)); | |
114 | - if (inp == NULL) | |
115 | + iptr = utf16_to_wchar(iptr, &wc, iend - iptr); | |
116 | + if (iptr == NULL) | |
115 | 117 | { |
116 | 118 | exfat_error("illegal UTF-16 sequence"); |
117 | 119 | return -EILSEQ; |
118 | 120 | } |
119 | - outp = wchar_to_utf8(outp, wc, outsize - (outp - output)); | |
120 | - if (outp == NULL) | |
121 | + optr = wchar_to_utf8(optr, wc, oend - optr); | |
122 | + if (optr == NULL) | |
121 | 123 | { |
122 | 124 | exfat_error("name is too long"); |
123 | 125 | return -ENAMETOOLONG; |
@@ -125,64 +127,69 @@ int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, | ||
125 | 127 | if (wc == 0) |
126 | 128 | return 0; |
127 | 129 | } |
128 | - if (outp - output >= outsize) | |
130 | + if (optr >= oend) | |
129 | 131 | { |
130 | 132 | exfat_error("name is too long"); |
131 | 133 | return -ENAMETOOLONG; |
132 | 134 | } |
133 | - *outp = '\0'; | |
135 | + *optr = '\0'; | |
134 | 136 | return 0; |
135 | 137 | } |
136 | 138 | |
137 | 139 | static const char* utf8_to_wchar(const char* input, wchar_t* wc, |
138 | 140 | size_t insize) |
139 | 141 | { |
140 | - if ((input[0] & 0x80) == 0 && insize >= 1) | |
142 | + size_t size; | |
143 | + size_t i; | |
144 | + | |
145 | + if (insize == 0) | |
146 | + exfat_bug("no input for utf8_to_wchar"); | |
147 | + | |
148 | + if ((input[0] & 0x80) == 0) | |
141 | 149 | { |
142 | 150 | *wc = (wchar_t) input[0]; |
143 | 151 | return input + 1; |
144 | 152 | } |
145 | - if ((input[0] & 0xe0) == 0xc0 && insize >= 2) | |
153 | + else if ((input[0] & 0xe0) == 0xc0) | |
146 | 154 | { |
147 | - *wc = (((wchar_t) input[0] & 0x1f) << 6) | | |
148 | - ((wchar_t) input[1] & 0x3f); | |
149 | - return input + 2; | |
155 | + *wc = ((wchar_t) input[0] & 0x1f) << 6; | |
156 | + size = 2; | |
150 | 157 | } |
151 | - if ((input[0] & 0xf0) == 0xe0 && insize >= 3) | |
158 | + else if ((input[0] & 0xf0) == 0xe0) | |
152 | 159 | { |
153 | - *wc = (((wchar_t) input[0] & 0x0f) << 12) | | |
154 | - (((wchar_t) input[1] & 0x3f) << 6) | | |
155 | - ((wchar_t) input[2] & 0x3f); | |
156 | - return input + 3; | |
160 | + *wc = ((wchar_t) input[0] & 0x0f) << 12; | |
161 | + size = 3; | |
157 | 162 | } |
158 | - if ((input[0] & 0xf8) == 0xf0 && insize >= 4) | |
163 | + else if ((input[0] & 0xf8) == 0xf0) | |
159 | 164 | { |
160 | - *wc = (((wchar_t) input[0] & 0x07) << 18) | | |
161 | - (((wchar_t) input[1] & 0x3f) << 12) | | |
162 | - (((wchar_t) input[2] & 0x3f) << 6) | | |
163 | - ((wchar_t) input[3] & 0x3f); | |
164 | - return input + 4; | |
165 | + *wc = ((wchar_t) input[0] & 0x07) << 18; | |
166 | + size = 4; | |
165 | 167 | } |
166 | - if ((input[0] & 0xfc) == 0xf8 && insize >= 5) | |
168 | + else if ((input[0] & 0xfc) == 0xf8) | |
167 | 169 | { |
168 | - *wc = (((wchar_t) input[0] & 0x03) << 24) | | |
169 | - (((wchar_t) input[1] & 0x3f) << 18) | | |
170 | - (((wchar_t) input[2] & 0x3f) << 12) | | |
171 | - (((wchar_t) input[3] & 0x3f) << 6) | | |
172 | - ((wchar_t) input[4] & 0x3f); | |
173 | - return input + 5; | |
170 | + *wc = ((wchar_t) input[0] & 0x03) << 24; | |
171 | + size = 5; | |
174 | 172 | } |
175 | - if ((input[0] & 0xfe) == 0xfc && insize >= 6) | |
173 | + else if ((input[0] & 0xfe) == 0xfc) | |
174 | + { | |
175 | + *wc = ((wchar_t) input[0] & 0x01) << 30; | |
176 | + size = 6; | |
177 | + } | |
178 | + else | |
179 | + return NULL; | |
180 | + | |
181 | + if (insize < size) | |
182 | + return NULL; | |
183 | + | |
184 | + /* the first byte is handled above */ | |
185 | + for (i = 1; i < size; i++) | |
176 | 186 | { |
177 | - *wc = (((wchar_t) input[0] & 0x01) << 30) | | |
178 | - (((wchar_t) input[1] & 0x3f) << 24) | | |
179 | - (((wchar_t) input[2] & 0x3f) << 18) | | |
180 | - (((wchar_t) input[3] & 0x3f) << 12) | | |
181 | - (((wchar_t) input[4] & 0x3f) << 6) | | |
182 | - ((wchar_t) input[5] & 0x3f); | |
183 | - return input + 6; | |
187 | + if ((input[i] & 0xc0) != 0x80) | |
188 | + return NULL; | |
189 | + *wc |= (input[i] & 0x3f) << ((size - i - 1) * 6); | |
184 | 190 | } |
185 | - return NULL; | |
191 | + | |
192 | + return input + size; | |
186 | 193 | } |
187 | 194 | |
188 | 195 | static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize) |
@@ -202,23 +209,25 @@ static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize) | ||
202 | 209 | return output + 2; |
203 | 210 | } |
204 | 211 | |
205 | -int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, | |
212 | +int exfat_utf8_to_utf16(le16_t* output, const char* input, size_t outsize, | |
206 | 213 | size_t insize) |
207 | 214 | { |
208 | - const char* inp = input; | |
209 | - le16_t* outp = output; | |
215 | + const char* iptr = input; | |
216 | + const char* iend = input + insize; | |
217 | + le16_t* optr = output; | |
218 | + const le16_t* oend = output + outsize; | |
210 | 219 | wchar_t wc; |
211 | 220 | |
212 | - while (inp - input < insize) | |
221 | + while (iptr < iend) | |
213 | 222 | { |
214 | - inp = utf8_to_wchar(inp, &wc, insize - (inp - input)); | |
215 | - if (inp == NULL) | |
223 | + iptr = utf8_to_wchar(iptr, &wc, iend - iptr); | |
224 | + if (iptr == NULL) | |
216 | 225 | { |
217 | 226 | exfat_error("illegal UTF-8 sequence"); |
218 | 227 | return -EILSEQ; |
219 | 228 | } |
220 | - outp = wchar_to_utf16(outp, wc, outsize - (outp - output)); | |
221 | - if (outp == NULL) | |
229 | + optr = wchar_to_utf16(optr, wc, oend - optr); | |
230 | + if (optr == NULL) | |
222 | 231 | { |
223 | 232 | exfat_error("name is too long"); |
224 | 233 | return -ENAMETOOLONG; |
@@ -226,16 +235,16 @@ int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, | ||
226 | 235 | if (wc == 0) |
227 | 236 | break; |
228 | 237 | } |
229 | - if (outp - output >= outsize) | |
238 | + if (optr >= oend) | |
230 | 239 | { |
231 | 240 | exfat_error("name is too long"); |
232 | 241 | return -ENAMETOOLONG; |
233 | 242 | } |
234 | - *outp = cpu_to_le16(0); | |
243 | + *optr = cpu_to_le16(0); | |
235 | 244 | return 0; |
236 | 245 | } |
237 | 246 | |
238 | -size_t utf16_length(const le16_t* str) | |
247 | +size_t exfat_utf16_length(const le16_t* str) | |
239 | 248 | { |
240 | 249 | size_t i = 0; |
241 | 250 |
@@ -48,7 +48,7 @@ void exfat_stat(const struct exfat* ef, const struct exfat_node* node, | ||
48 | 48 | void exfat_get_name(const struct exfat_node* node, |
49 | 49 | char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]) |
50 | 50 | { |
51 | - if (utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX, | |
51 | + if (exfat_utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX, | |
52 | 52 | EXFAT_NAME_MAX) != 0) |
53 | 53 | exfat_bug("failed to convert name to UTF-8"); |
54 | 54 | } |
@@ -60,7 +60,7 @@ static uint16_t add_checksum_byte(uint16_t sum, uint8_t byte) | ||
60 | 60 | |
61 | 61 | static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n) |
62 | 62 | { |
63 | - int i; | |
63 | + size_t i; | |
64 | 64 | |
65 | 65 | for (i = 0; i < n; i++) |
66 | 66 | sum = add_checksum_byte(sum, ((const uint8_t*) buffer)[i]); |
@@ -70,7 +70,7 @@ static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n) | ||
70 | 70 | uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry) |
71 | 71 | { |
72 | 72 | uint16_t sum = 0; |
73 | - int i; | |
73 | + size_t i; | |
74 | 74 | |
75 | 75 | for (i = 0; i < sizeof(struct exfat_entry); i++) |
76 | 76 | if (i != 2 && i != 3) /* skip checksum field itself */ |
@@ -178,3 +178,15 @@ void exfat_print_info(const struct exfat_super_block* sb, | ||
178 | 178 | exfat_humanize_bytes(avail_space, &hb); |
179 | 179 | printf("Available space %10"PRIu64" %s\n", hb.value, hb.unit); |
180 | 180 | } |
181 | + | |
182 | +bool exfat_match_option(const char* options, const char* option_name) | |
183 | +{ | |
184 | + const char* p; | |
185 | + size_t length = strlen(option_name); | |
186 | + | |
187 | + for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name)) | |
188 | + if ((p == options || p[-1] == ',') && | |
189 | + (p[length] == ',' || p[length] == '\0')) | |
190 | + return true; | |
191 | + return false; | |
192 | +} |
@@ -121,9 +121,9 @@ static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size) | ||
121 | 121 | return user_defined; |
122 | 122 | } |
123 | 123 | |
124 | - if (volume_size < 256ull * 1024 * 1024) | |
124 | + if (volume_size < 256LL * 1024 * 1024) | |
125 | 125 | return MAX(0, 12 - sector_bits); /* 4 KB */ |
126 | - if (volume_size < 32ull * 1024 * 1024 * 1024) | |
126 | + if (volume_size < 32LL * 1024 * 1024 * 1024) | |
127 | 127 | return MAX(0, 15 - sector_bits); /* 32 KB */ |
128 | 128 | |
129 | 129 | for (i = 17; ; i++) /* 128 KB or more */ |
@@ -136,7 +136,7 @@ static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s) | ||
136 | 136 | memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t)); |
137 | 137 | if (s == NULL) |
138 | 138 | return 0; |
139 | - return utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s)); | |
139 | + return exfat_utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s)); | |
140 | 140 | } |
141 | 141 | |
142 | 142 | static uint32_t setup_volume_serial(uint32_t user_defined) |
@@ -178,7 +178,7 @@ static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits, | ||
178 | 178 | |
179 | 179 | static int logarithm2(int n) |
180 | 180 | { |
181 | - int i; | |
181 | + size_t i; | |
182 | 182 | |
183 | 183 | for (i = 0; i < sizeof(int) * CHAR_BIT - 1; i++) |
184 | 184 | if ((1 << i) == n) |
@@ -52,7 +52,7 @@ static int check_size(off_t volume_size) | ||
52 | 52 | } |
53 | 53 | |
54 | 54 | static int erase_object(struct exfat_dev* dev, const void* block, |
55 | - size_t block_size, off_t start, off_t size) | |
55 | + off_t block_size, off_t start, off_t size) | |
56 | 56 | { |
57 | 57 | const off_t block_count = DIV_ROUND_UP(size, block_size); |
58 | 58 | off_t i; |
@@ -78,12 +78,12 @@ static int erase(struct exfat_dev* dev) | ||
78 | 78 | { |
79 | 79 | const struct fs_object** pp; |
80 | 80 | off_t position = 0; |
81 | - const size_t block_size = 1024 * 1024; | |
81 | + const off_t block_size = 1024 * 1024; | |
82 | 82 | void* block = malloc(block_size); |
83 | 83 | |
84 | 84 | if (block == NULL) |
85 | 85 | { |
86 | - exfat_error("failed to allocate erase block of %zu bytes", block_size); | |
86 | + exfat_error("failed to allocate erase block"); | |
87 | 87 | return 1; |
88 | 88 | } |
89 | 89 | memset(block, 0, block_size); |
@@ -41,12 +41,12 @@ static void init_label_entry(struct exfat_entry_label* label_entry) | ||
41 | 41 | memset(label_entry, 0, sizeof(struct exfat_entry_label)); |
42 | 42 | label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID; |
43 | 43 | |
44 | - if (utf16_length(get_volume_label()) == 0) | |
44 | + if (exfat_utf16_length(get_volume_label()) == 0) | |
45 | 45 | return; |
46 | 46 | |
47 | 47 | memcpy(label_entry->name, get_volume_label(), |
48 | 48 | EXFAT_ENAME_MAX * sizeof(le16_t)); |
49 | - label_entry->length = utf16_length(get_volume_label()); | |
49 | + label_entry->length = exfat_utf16_length(get_volume_label()); | |
50 | 50 | label_entry->type |= EXFAT_ENTRY_VALID; |
51 | 51 | } |
52 | 52 |