FreeBSD Bugzilla – Attachment 145599 Details for
Bug 153426
[patch] fsck_msdosfs(8) only works with sector size 512
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated Bruce's patch to apply on FreeBSD 10 (and 11)
fsck_msdos-bigsectors.diff (text/plain), 5.65 KB, created by
Pedro F. Giffuni
on 2014-08-10 01:10:49 UTC
(
hide
)
Description:
Updated Bruce's patch to apply on FreeBSD 10 (and 11)
Filename:
MIME Type:
Creator:
Pedro F. Giffuni
Created:
2014-08-10 01:10:49 UTC
Size:
5.65 KB
patch
obsolete
>Index: sbin/fsck_msdosfs/boot.c >=================================================================== >--- sbin/fsck_msdosfs/boot.c (revision 269767) >+++ sbin/fsck_msdosfs/boot.c (working copy) >@@ -39,25 +39,56 @@ > #include "ext.h" > #include "fsutil.h" > >+#define IOSIZE 65536 >+ > int > readboot(int dosfs, struct bootblock *boot) > { >+ u_char ioblock[IOSIZE]; >+ u_char iofsinfo[IOSIZE]; >+ u_char iobackup[IOSIZE]; > u_char block[DOSBOOTBLOCKSIZE]; > u_char fsinfo[2 * DOSBOOTBLOCKSIZE]; > u_char backup[DOSBOOTBLOCKSIZE]; >+ u_char *infop; >+ size_t iosize; >+ u_int secsize; > int ret = FSOK; > int i; > >- if ((size_t)read(dosfs, block, sizeof block) != sizeof block) { >+ /* Search for an i/o size that works. */ >+ for (iosize = IOSIZE; iosize >= DOSBOOTBLOCKSIZE; iosize >>= 1) { >+ if (lseek(dosfs, (off_t)0, SEEK_SET) == 0 && >+ read(dosfs, ioblock, iosize) == (ssize_t)iosize) >+ break; >+ } >+ if (iosize < DOSBOOTBLOCKSIZE) { > perr("could not read boot block"); > return FSFATAL; > } >+ memcpy(block, ioblock, sizeof block); > >- if (block[510] != 0x55 || block[511] != 0xaa) { >- pfatal("Invalid signature in boot block: %02x%02x", >- block[511], block[510]); >+ /* >+ * Preliminary decode to determine where the signature might be. >+ * It is supposed to be at the end of a 512-block, but we used to >+ * put it at the end of a sector. Accept the latter so as to fix >+ * it someday. >+ */ >+ secsize = block[11] + (block[12] << 8); >+ if (secsize < sizeof block || secsize > IOSIZE) { >+ perror("Preposterous or unsupported sector size"); > return FSFATAL; > } >+ if (block[510] != 0x55 || block[511] != 0xaa) { >+ if (ioblock[secsize - 2] != 0x55 || >+ ioblock[secsize - 1] != 0xaa) { >+ pfatal("Invalid signature in boot block: %02x%02x", >+ block[511], block[510]); >+ return FSFATAL; >+ } >+ pwarn( >+ "Invalid primary signature in boot block -- using secondary\n"); >+ } > > memset(boot, 0, sizeof *boot); > boot->ValidFat = -1; >@@ -100,12 +131,14 @@ > boot->bpbFSInfo = block[48] + (block[49] << 8); > boot->bpbBackup = block[50] + (block[51] << 8); > >+ iosize = (secsize >= sizeof fsinfo) ? secsize : sizeof fsinfo; > if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, > SEEK_SET) != boot->bpbFSInfo * boot->bpbBytesPerSec >- || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) { >+ || read(dosfs, iofsinfo, iosize) != (ssize_t)iosize) { > perr("could not read fsinfo block"); > return FSFATAL; > } >+ memcpy(fsinfo, iofsinfo, sizeof fsinfo); > if (memcmp(fsinfo, "RRaA", 4) > || memcmp(fsinfo + 0x1e4, "rrAa", 4) > || fsinfo[0x1fc] >@@ -116,6 +149,24 @@ > || fsinfo[0x3fd] > || fsinfo[0x3fe] != 0x55 > || fsinfo[0x3ff] != 0xaa) { >+ infop = &iofsinfo[secsize - DOSBOOTBLOCKSIZE]; >+ if (memcmp(fsinfo, "RRaA", 4) == 0 && >+ memcmp(infop + 0x1e4, "rrAa", 4) == 0 && >+ infop[0x1fc] == 0 && >+ infop[0x1fd] == 0 && >+ infop[0x1fe] == 0x55 && >+ infop[0x1ff] == 0xaa) { >+ pwarn( >+ "Invalid signature in fsinfo block -- using secondary\n"); >+ /* >+ * Silently fix up the actual fsinfo data >+ * (just 2 32-bit words) since this data >+ * is advisory and the indentation is >+ * already too painful to ask about this. >+ */ >+ memcpy(fsinfo + 0x1e8, infop + 0x1e8, 8); >+ goto over; >+ } > pwarn("Invalid signature in fsinfo block\n"); > if (ask(0, "Fix")) { > memcpy(fsinfo, "RRaA", 4); >@@ -126,15 +177,17 @@ > fsinfo[0x3fc] = fsinfo[0x3fd] = 0; > fsinfo[0x3fe] = 0x55; > fsinfo[0x3ff] = 0xaa; >+ memcpy(iofsinfo, fsinfo, sizeof fsinfo); > if (lseek(dosfs, boot->bpbFSInfo * > boot->bpbBytesPerSec, SEEK_SET) > != boot->bpbFSInfo * boot->bpbBytesPerSec >- || write(dosfs, fsinfo, sizeof fsinfo) >- != sizeof fsinfo) { >+ || write(dosfs, iofsinfo, iosize) >+ != (ssize_t)iosize) { > perr("Unable to write bpbFSInfo"); > return FSFATAL; > } > ret = FSBOOTMOD; >+over: ; > } else > boot->bpbFSInfo = 0; > } >@@ -150,10 +203,11 @@ > if (lseek(dosfs, boot->bpbBackup * boot->bpbBytesPerSec, > SEEK_SET) > != boot->bpbBackup * boot->bpbBytesPerSec >- || read(dosfs, backup, sizeof backup) != sizeof backup) { >+ || read(dosfs, iobackup, secsize) != (ssize_t)secsize) { > perr("could not read backup bootblock"); > return FSFATAL; > } >+ memcpy(backup, iobackup, sizeof backup); > backup[65] = block[65]; /* XXX */ > if (memcmp(block + 11, backup + 11, 79)) { > /* >@@ -237,14 +291,20 @@ > int > writefsinfo(int dosfs, struct bootblock *boot) > { >+ u_char iofsinfo[IOSIZE]; > u_char fsinfo[2 * DOSBOOTBLOCKSIZE]; >+ size_t iosize; >+ u_int secsize; > >+ secsize = boot->bpbBytesPerSec; >+ iosize = (secsize >= sizeof fsinfo) ? secsize : sizeof fsinfo; > if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET) > != boot->bpbFSInfo * boot->bpbBytesPerSec >- || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) { >+ || read(dosfs, iofsinfo, iosize) != (ssize_t)iosize) { > perr("could not read fsinfo block"); > return FSFATAL; > } >+ memcpy(fsinfo, iofsinfo, sizeof fsinfo); > fsinfo[0x1e8] = (u_char)boot->FSFree; > fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8); > fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16); >@@ -253,10 +313,10 @@ > fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8); > fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16); > fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24); >+ memcpy(iofsinfo, fsinfo, sizeof fsinfo); > if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET) > != boot->bpbFSInfo * boot->bpbBytesPerSec >- || write(dosfs, fsinfo, sizeof fsinfo) >- != sizeof fsinfo) { >+ || write(dosfs, iofsinfo, iosize) != (ssize_t)iosize) { > perr("Unable to write bpbFSInfo"); > return FSFATAL; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 153426
: 145599