File dosfstools-add-g.patch of Package dosfstools.22274

From e579a7df89bb3a6df08847d45c70c8ebfabca7d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com>
Date: Sat, 17 Nov 2018 01:12:52 +0100
Subject: [PATCH] mkfs.fat: Allow to specify disk geometry via new -g option

Backported.

---
 manpages/mkfs.fat.8.in |  8 ++++++++
 src/mkfs.fat.c         | 25 ++++++++++++++++++++++---
 2 files changed, 30 insertions(+), 3 deletions(-)

Index: dosfstools-4.1/manpages/mkfs.fat.8.in
===================================================================
--- dosfstools-4.1.orig/manpages/mkfs.fat.8.in
+++ dosfstools-4.1/manpages/mkfs.fat.8.in
@@ -89,6 +89,14 @@ The default is 2.
 Specifies the type of file allocation tables used (12, 16 or 32 bit).
 If nothing is specified, \fBmkfs.fat\fR will automatically select between 12, 16
 and 32 bit, whatever fits better for the filesystem size.
+.IP "\fB\-g\fR \fIHEADS\fR/\fISECTORS-PER-TRACK\fR" 4
+Specify \fIHEADS\fR and \fISECTORS-PER-TRACK\fR numbers which represents
+disk geometry of \fIDEVICE\fR. Both numbers are stored into the FAT boot sector.
+Number \fISECTORS-PER-TRACK\fR is used also for aligning the total count of FAT
+sectors. By default disk geometry is read from \fIDEVICE\fR itself. If it is not
+available then \fILBA-Assist Translation\fR and translation table from the
+\fISD Card Part 2 File System Specification\fR based on total number of disk
+sectors is used.
 .IP "\fB\-h\fR \fINUMBER-OF-HIDDEN-SECTORS\fR" 4
 Select the number of hidden sectors in the volume.
 Apparently some digital cameras get indigestion if you feed them a CF card
Index: dosfstools-4.1/src/mkfs.fat.c
===================================================================
--- dosfstools-4.1.orig/src/mkfs.fat.c
+++ dosfstools-4.1/src/mkfs.fat.c
@@ -620,8 +620,10 @@ static void establish_params(struct devi
     if (!root_dir_entries)
 	root_dir_entries = def_root_dir_entries;
 
-    bs.secs_track = htole16(sec_per_track);
-    bs.heads = htole16(heads);
+    if (!bs.secs_track)
+        bs.secs_track = htole16(sec_per_track);
+    if (!bs.heads)
+        bs.heads = htole16(heads);
     bs.media = media;
     bs.cluster_size = cluster_size;
 }
@@ -1268,9 +1270,9 @@ static void usage(int exitval)
 Usage: mkfs.fat [-a][-A][-c][-C][-v][-I][-l bad-block-file][-b backup-boot-sector]\n\
        [-m boot-msg-file][-n volume-name][-i volume-id]\n\
        [-s sectors-per-cluster][-S logical-sector-size][-f number-of-FATs]\n\
-       [-h hidden-sectors][-F fat-size][-r root-dir-entries][-R reserved-sectors]\n\
-       [-M FAT-media-byte][-D drive_number]\n\
-       [--invariant]\n\
+       [-h hidden-sectors][-F fat-size][-g heads/sector_per_track]\n\
+       [-r root-dir-entries][-R reserved-sectors][-M FAT-media-byte]\n\
+       [-D drive_number][--invariant]\n\
        [--help]\n\
        /dev/name [blocks]\n");
     exit(exitval);
@@ -1319,6 +1321,7 @@ int main(int argc, char **argv)
     uint64_t cblocks = 0;
     int blocks_specified = 0;
     struct timeval create_timeval;
+    long long conversion;
 
     enum {OPT_HELP=1000, OPT_INVARIANT,};
     const struct option long_options[] = {
@@ -1341,7 +1344,7 @@ int main(int argc, char **argv)
 
     printf("mkfs.fat " VERSION " (" VERSION_DATE ")\n");
 
-    while ((c = getopt_long(argc, argv, "aAb:cCf:D:F:Ii:l:m:M:n:r:R:s:S:h:v",
+    while ((c = getopt_long(argc, argv, "aAb:cCf:D:F:g:Ii:l:m:M:n:r:R:s:S:h:v",
 				    long_options, NULL)) != -1)
 	/* Scan the command line for options */
 	switch (c) {
@@ -1396,6 +1399,22 @@ int main(int argc, char **argv)
 	    size_fat_by_user = 1;
 	    break;
 
+	case 'g':		/* g : geometry: heads and sectors per track */
+	    errno = 0;
+	    conversion = strtol(optarg, &tmp, 0);
+	    if (!*optarg || isspace(*optarg) || tmp[0] != '/' || !tmp[1] || isspace(tmp[1]) || errno || conversion <= 0 || conversion > UINT16_MAX) {
+		printf("Bad format of geometry : %s\n", optarg);
+		usage(1);
+	    }
+	    bs.heads = htole16(conversion);
+	    conversion = strtol(tmp+1, &tmp, 0);
+	    if (*tmp || errno || conversion <= 0 || conversion > UINT16_MAX) {
+		printf("Bad format of geometry : %s\n", optarg);
+		usage(1);
+	    }
+	    bs.secs_track = htole16(conversion);
+	    break;
+
 	case 'h':		/* h : number of hidden sectors */
 	    hidden_sectors = (int)strtol(optarg, &tmp, 0);
 	    if (*tmp || hidden_sectors < 0) {
openSUSE Build Service is sponsored by