Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
dosfstools
fix-calculation.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fix-calculation.patch of Package dosfstools
From b29eb5be67e9e8a06908ee10f6c205cb609b1021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com> Date: Wed, 15 Aug 2018 15:15:06 +0200 Subject: [PATCH 1/7] mkfs.fat: Align total number of sectors to be multiple of sectors per track This requirement is needed by DOS systems and also by Linux mtools project. Without proper alignment, mtools applications refuse to work on such filesystem. --- configure.ac | 2 src/mkfs.fat.c | 119 ++++++++++++++++++++++------------------------- tests/Makefile.am | 3 - tests/mkfs-fat32_4K.mkfs | 3 + tests/mkfs-fat32_4K.xxd | 63 ++++++++++++++++++++++++ tests/referenceFAT32.xxd | 5 + 6 files changed, 132 insertions(+), 63 deletions(-) --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ AC_INIT([dosfstools], [4.1]) AC_SUBST([RELEASE_DATE], [2017-01-24]) -AM_INIT_AUTOMAKE([1.11 foreign subdir-objects parallel-tests]) +AM_INIT_AUTOMAKE([1.15.1 foreign subdir-objects parallel-tests]) AC_ARG_ENABLE([compat-symlinks], [AS_HELP_STRING([--enable-compat-symlinks], --- a/src/mkfs.fat.c +++ b/src/mkfs.fat.c @@ -7,6 +7,7 @@ Copyright (C) 1998-2005 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> Copyright (C) 2015-2016 Andreas Bombe <aeb@debian.org> + Copyright (C) 2018 Pali Rohár <pali.rohar@gmail.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -107,14 +108,26 @@ static inline int cdiv(int a, int b) #define BOOT_SIGN 0xAA55 /* Boot sector magic number */ -#define MAX_CLUST_12 ((1 << 12) - 16) -#define MAX_CLUST_16 ((1 << 16) - 16) -#define MIN_CLUST_32 65529 +/* According to Microsoft FAT specification (fatgen103.doc) disk with + * 4085 clusters (or more) is FAT16, but Microsoft Windows FAT driver + * fastfat.sys detects disk with less then 4087 clusters as FAT12. + * Linux FAT drivers msdos.ko and vfat.ko detect disk with at least + * 4085 clusters as FAT16, therefore for compatibility reasons with + * both systems disallow formatting disks to 4085 or 4086 clusters. */ +#define MAX_CLUST_12 4084 +#define MIN_CLUST_16 4087 + +/* According to Microsoft FAT specification (fatgen103.doc) disk with + * 65525 clusters (or more) is FAT32, but Microsoft Windows FAT driver + * fastfat.sys, Linux FAT drivers msdos.ko and vfat.ko detect disk as + * FAT32 when Sectors Per FAT (fat_length) is set to zero. And not by + * number of clusters. Still there is cluster upper limit for FAT16. */ +#define MAX_CLUST_16 65524 +#define MIN_CLUST_32 65525 + /* M$ says the high 4 bits of a FAT32 FAT entry are reserved and don't belong * to the cluster number. So the max. cluster# is based on 2^28 */ -#define MAX_CLUST_32 ((1 << 28) - 16) - -#define FAT12_THRESHOLD 4085 +#define MAX_CLUST_32 268435446 #define OLDGEMDOS_MAX_SECTORS 32765 #define GEMDOS_MAX_SECTORS 65531 @@ -588,13 +601,12 @@ static void establish_params(struct devi * fs size <= 16G: 8k clusters * fs size <= 32G: 16k clusters * fs size > 32G: 32k clusters - * - * This only works correctly for 512 byte sectors! */ - uint32_t sz_mb = info->size / (1024 * 1024); - cluster_size = - sz_mb > 32 * 1024 ? 64 : sz_mb > 16 * 1024 ? 32 : sz_mb > - 8 * 1024 ? 16 : sz_mb > 260 ? 8 : 1; + unsigned long long int sectors = info->size / sector_size; + cluster_size = sectors > 32*1024*1024*2 ? 64 : + sectors > 16*1024*1024*2 ? 32 : + sectors > 8*1024*1024*2 ? 16 : + sectors > 260*1024*2 ? 8 : 1; } if (info->geom_heads > 0) { @@ -733,6 +745,9 @@ static void setup_tables(void) (long long)(blocks * BLOCK_SIZE / sector_size) + orphaned_sectors; } + /* Align number of sectors to be multiple of sectors per track, needed by DOS and mtools */ + num_sectors = num_sectors / le16toh(bs.secs_track) * le16toh(bs.secs_track); + if (!atari_format) { unsigned fatdata1216; /* Sectors for FATs + data area (FAT12/16) */ unsigned fatdata32; /* Sectors for FATs + data area (FAT32) */ @@ -781,13 +796,13 @@ static void setup_tables(void) maxclust12 = (fatlength12 * 2 * sector_size) / 3; if (maxclust12 > MAX_CLUST_12) maxclust12 = MAX_CLUST_12; - if (verbose >= 2) - printf("FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + if (verbose >= 2 && (size_fat == 0 || size_fat == 12)) + printf("Trying FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", clust12, fatlength12, maxclust12, MAX_CLUST_12); - if (clust12 > maxclust12 - 2) { + if (clust12 > maxclust12) { clust12 = 0; - if (verbose >= 2) - printf("FAT12: too much clusters\n"); + if (verbose >= 2 && (size_fat == 0 || size_fat == 12)) + printf("Trying FAT12: too much clusters\n"); } clust16 = ((long long)fatdata1216 * sector_size + nr_fats * 4) / @@ -801,20 +816,19 @@ static void setup_tables(void) maxclust16 = (fatlength16 * sector_size) / 2; if (maxclust16 > MAX_CLUST_16) maxclust16 = MAX_CLUST_16; - if (verbose >= 2) - printf("FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", - clust16, fatlength16, maxclust16, MAX_CLUST_16); - if (clust16 > maxclust16 - 2) { - if (verbose >= 2) - printf("FAT16: too much clusters\n"); + if (verbose >= 2 && (size_fat == 0 || size_fat == 16)) + printf("Trying FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u/%u\n", + clust16, fatlength16, maxclust16, MIN_CLUST_16, MAX_CLUST_16); + if (clust16 > maxclust16) { + if (verbose >= 2 && (size_fat == 0 || size_fat == 16)) + printf("Trying FAT16: too much clusters\n"); clust16 = 0; } - /* The < 4078 avoids that the filesystem will be misdetected as having a + /* This avoids that the filesystem will be misdetected as having a * 12 bit FAT. */ - if (clust16 < FAT12_THRESHOLD - && !(size_fat_by_user && size_fat == 16)) { - if (verbose >= 2) - printf("FAT16: would be misdetected as FAT12\n"); + if (clust16 && clust16 < MIN_CLUST_16) { + if (verbose >= 2 && (size_fat == 0 || size_fat == 16)) + printf("Trying FAT16: not enough clusters, would be misdetected as FAT12\n"); clust16 = 0; } @@ -829,19 +843,20 @@ static void setup_tables(void) maxclust32 = (fatlength32 * sector_size) / 4; if (maxclust32 > MAX_CLUST_32) maxclust32 = MAX_CLUST_32; - if (clust32 && clust32 < MIN_CLUST_32 - && !(size_fat_by_user && size_fat == 32)) { + if (verbose >= 2 && (size_fat == 0 || size_fat == 32)) + printf("Trying FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u/%u\n", + clust32, fatlength32, maxclust32, MIN_CLUST_32, MAX_CLUST_32); + if (clust32 > maxclust32) { + if (verbose >= 2 && (size_fat == 0 || size_fat == 32)) + printf("Trying FAT32: too much clusters\n"); clust32 = 0; - if (verbose >= 2) - printf("FAT32: not enough clusters (%d)\n", MIN_CLUST_32); } - if (verbose >= 2) - printf("FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", - clust32, fatlength32, maxclust32, MAX_CLUST_32); - if (clust32 > maxclust32) { + /* When explicitely asked, allow to create FAT32 with less then MIN_CLUST_32 */ + if (clust32 && clust32 < MIN_CLUST_32 + && !(size_fat_by_user && size_fat == 32)) { + if (verbose >= 2 && (size_fat == 0 || size_fat == 32)) + printf("Trying FAT32: not enough clusters\n"); clust32 = 0; - if (verbose >= 2) - printf("FAT32: too much clusters\n"); } if ((clust12 && (size_fat == 0 || size_fat == 12)) || @@ -869,23 +884,6 @@ static void setup_tables(void) break; case 16: - if (clust16 < FAT12_THRESHOLD) { - if (size_fat_by_user) { - fprintf(stderr, "WARNING: Not enough clusters for a " - "16 bit FAT! The filesystem will be\n" - "misinterpreted as having a 12 bit FAT without " - "mount option \"fat=16\".\n"); - } else { - fprintf(stderr, "This filesystem has an unfortunate size. " - "A 12 bit FAT cannot provide\n" - "enough clusters, but a 16 bit FAT takes up a little " - "bit more space so that\n" - "the total number of clusters becomes less than the " - "threshold value for\n" - "distinction between 12 and 16 bit FATs.\n"); - die("Make the filesystem a bit smaller manually."); - } - } cluster_count = clust16; fat_length = fatlength16; bs.fat_length = htole16(fatlength16); @@ -894,8 +892,7 @@ static void setup_tables(void) case 32: if (clust32 < MIN_CLUST_32) - fprintf(stderr, - "WARNING: Not enough clusters for a 32 bit FAT!\n"); + fprintf(stderr, "WARNING: Number of clusters for 32 bit FAT is less then suggested minimum.\n"); cluster_count = clust32; fat_length = fatlength32; bs.fat_length = htole16(0); @@ -1053,9 +1050,9 @@ static void setup_tables(void) if (!cluster_count) { if (sectors_per_cluster) /* If yes, die if we'd spec'd sectors per cluster */ - die("Too many clusters for filesystem - try more sectors per cluster"); + die("Not enough or too many clusters for filesystem - try less or more sectors per cluster"); else - die("Attempting to create a too large filesystem"); + die("Attempting to create a too small or a too large filesystem"); } fat_entries = cluster_count + 2; @@ -1076,8 +1073,8 @@ static void setup_tables(void) (le16toh(bs.secs_track) != 1) ? "s" : ""); printf("hidden sectors 0x%04x;\n", hidden_sectors); printf("logical sector size is %d,\n", sector_size); - printf("using 0x%02x media descriptor, with %d sectors;\n", - (int)(bs.media), num_sectors); + printf("using 0x%02x media descriptor, with %u sectors;\n", + (int)(bs.media), (unsigned)num_sectors); printf("drive number 0x%02x;\n", (int) (vi->drive_number)); printf("filesystem has %d %d-bit FAT%s and %d sector%s per cluster.\n", (int)(bs.fats), size_fat, (bs.fats != 1) ? "s" : "", --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,7 +6,6 @@ endif TESTS = referenceFAT12.mkfs \ referenceFAT16.mkfs \ - referenceFAT32.mkfs \ check-bad_names.fsck \ check-chain_to_free_cluster.fsck \ check-chain_too_long.fsck \ @@ -28,6 +27,8 @@ dist_check_DATA = test-mkfs test-fsck referenceFAT16.xxd \ referenceFAT32.mkfs \ referenceFAT32.xxd \ + mkfs-fat32_4K.mkfs \ + mkfs-fat32_4K.xxd \ check-bad_names.fsck \ check-chain_to_free_cluster.fsck \ check-chain_too_long.fsck \ --- /dev/null +++ b/tests/mkfs-fat32_4K.mkfs @@ -0,0 +1,3 @@ +ARGS="-n TEST4K -S 4096" +SIZE=614400 +CMP_LIMIT=10M --- /dev/null +++ b/tests/mkfs-fat32_4K.xxd @@ -0,0 +1,63 @@ +00000000: eb58 906d 6b66 732e 6661 7400 1001 2000 .X.mkfs.fat... . +00000010: 0200 0000 00f8 0000 2000 0800 0000 0000 ........ ....... +00000020: 0058 0200 9600 0000 0000 0000 0200 0000 .X.............. +00000030: 0100 0600 0000 0000 0000 0000 0000 0000 ................ +00000040: 8000 29cd ab34 1254 4553 5434 4b20 2020 ..)..4.TEST4K +00000050: 2020 4641 5433 3220 2020 0e1f be77 7cac FAT32 ...w|. +00000060: 22c0 740b 56b4 0ebb 0700 cd10 5eeb f032 ".t.V.......^..2 +00000070: e4cd 16cd 19eb fe54 6869 7320 6973 206e .......This is n +00000080: 6f74 2061 2062 6f6f 7461 626c 6520 6469 ot a bootable di +00000090: 736b 2e20 2050 6c65 6173 6520 696e 7365 sk. Please inse +000000a0: 7274 2061 2062 6f6f 7461 626c 6520 666c rt a bootable fl +000000b0: 6f70 7079 2061 6e64 0d0a 7072 6573 7320 oppy and..press +000000c0: 616e 7920 6b65 7920 746f 2074 7279 2061 any key to try a +000000d0: 6761 696e 202e 2e2e 200d 0a00 0000 0000 gain ... ....... +000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U. +00000200: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +00001000: 5252 6141 0000 0000 0000 0000 0000 0000 RRaA............ +00001010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +000011e0: 0000 0000 7272 4161 b356 0200 0200 0000 ....rrAa.V...... +000011f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U. +00001200: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +00006000: eb58 906d 6b66 732e 6661 7400 1001 2000 .X.mkfs.fat... . +00006010: 0200 0000 00f8 0000 2000 0800 0000 0000 ........ ....... +00006020: 0058 0200 9600 0000 0000 0000 0200 0000 .X.............. +00006030: 0100 0600 0000 0000 0000 0000 0000 0000 ................ +00006040: 8000 29cd ab34 1254 4553 5434 4b20 2020 ..)..4.TEST4K +00006050: 2020 4641 5433 3220 2020 0e1f be77 7cac FAT32 ...w|. +00006060: 22c0 740b 56b4 0ebb 0700 cd10 5eeb f032 ".t.V.......^..2 +00006070: e4cd 16cd 19eb fe54 6869 7320 6973 206e .......This is n +00006080: 6f74 2061 2062 6f6f 7461 626c 6520 6469 ot a bootable di +00006090: 736b 2e20 2050 6c65 6173 6520 696e 7365 sk. Please inse +000060a0: 7274 2061 2062 6f6f 7461 626c 6520 666c rt a bootable fl +000060b0: 6f70 7079 2061 6e64 0d0a 7072 6573 7320 oppy and..press +000060c0: 616e 7920 6b65 7920 746f 2074 7279 2061 any key to try a +000060d0: 6761 696e 202e 2e2e 200d 0a00 0000 0000 gain ... ....... +000060e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +000061f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U. +00006200: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +00007000: 5252 6141 0000 0000 0000 0000 0000 0000 RRaA............ +00007010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +000071e0: 0000 0000 7272 4161 b356 0200 0200 0000 ....rrAa.V...... +000071f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U. +00007200: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +00020000: f8ff ff0f ffff ff0f f8ff ff0f 0000 0000 ................ +00020010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +000b6000: f8ff ff0f ffff ff0f f8ff ff0f 0000 0000 ................ +000b6010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +0014c000: 5445 5354 344b 2020 2020 2008 0000 5a4b TEST4K ...ZK +0014c010: 6e46 6e46 0000 5a4b 6e46 0000 0000 0000 nFnF..ZKnF...... +0014c020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +257ffff0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ --- a/tests/referenceFAT32.xxd +++ b/tests/referenceFAT32.xxd @@ -52,3 +52,8 @@ 001f8020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 3e7ffff0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +001f8000: 5445 5354 4641 5433 3220 2008 0000 5a4b TESTFAT32 ...ZK +001f8010: 6e46 6e46 0000 5a4b 6e46 0000 0000 0000 nFnF..ZKnF...... +001f8020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +* +3e7ffff0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor