Skip to content

Commit

Permalink
Merge pull request #1822 from ghaerr/dos2
Browse files Browse the repository at this point in the history
[cmds] Remove fsck-dos FAT32 support allowing it to work on floppies
  • Loading branch information
ghaerr authored Mar 7, 2024
2 parents a794526 + 3b40fdd commit 5d82c65
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 30 deletions.
2 changes: 2 additions & 0 deletions elkscmd/fsck_dos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ include $(BASEDIR)/Make.rules
###############################################################################

LOCALCFLAGS = -Dlint -DELKS=1
# remove next line when FAT32 supported
LOCALCFLAGS += -Wno-shift-count-overflow

PRGS = fsck-dos

Expand Down
14 changes: 10 additions & 4 deletions elkscmd/fsck_dos/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ readboot(dosfs, boot)
struct bootblock *boot;
{
u_char block[DOSBOOTBLOCKSIZE];
u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
u_char backup[DOSBOOTBLOCKSIZE];
int ret = FSOK;

if (read(dosfs, block, sizeof block) < sizeof block) {
Expand Down Expand Up @@ -94,6 +92,13 @@ readboot(dosfs, boot)
if (!boot->RootDirEnts)
boot->flags |= FAT32;
if (boot->flags & FAT32) {
#ifdef ELKS
printf("Sorry, FAT32 checking not supported on ELKS\n");
exit(2);
#else
u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
u_char backup[DOSBOOTBLOCKSIZE];

boot->FATsecs = block[36] + ((U32)block[37] << 8)
+ ((U32)block[38] << 16) + ((U32)block[39] << 24);
if (block[40] & 0x80)
Expand Down Expand Up @@ -196,6 +201,7 @@ readboot(dosfs, boot)
pwarn("%s\n", tmp);
}
/* Check backup FSInfo? XXX */
#endif /* !ELKS */
}

boot->ClusterOffset = (boot->RootDirEnts * 32 + boot->BytesPerSec - 1)
Expand Down Expand Up @@ -227,7 +233,7 @@ readboot(dosfs, boot)
boot->ClustMask = CLUST16_MASK;
else {
pfatal("Filesystem too big (%lu clusters) for non-FAT32 partition",
boot->NumClusters);
(U32)boot->NumClusters);
return FSFATAL;
}

Expand All @@ -245,7 +251,7 @@ readboot(dosfs, boot)

if (boot->NumFatEntries < boot->NumClusters) {
pfatal("FAT size too small, %lu entries won't fit into %lu sectors\n",
boot->NumClusters, boot->FATsecs);
(U32)boot->NumClusters, (U32)boot->FATsecs);
return FSFATAL;
}
boot->ClusterSize = boot->BytesPerSec * boot->SecPerClust;
Expand Down
10 changes: 5 additions & 5 deletions elkscmd/fsck_dos/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ resetDosDirSection(struct bootblock *boot, struct fatEntry *fat)
if (boot->flags & FAT32) {
if (boot->RootCl < CLUST_FIRST || boot->RootCl >= boot->NumClusters) {
pfatal("Root directory starts with cluster out of range(%lu)",
boot->RootCl);
(U32)boot->RootCl);
return FSFATAL;
}
cl = fat[boot->RootCl].next;
Expand Down Expand Up @@ -400,7 +400,7 @@ checksize(struct bootblock *boot, struct fatEntry *fat, u_char *p,
else {
if (dir->head < CLUST_FIRST || dir->head >= boot->NumClusters)
return FSERROR;
physicalSize = fat[dir->head].length * boot->ClusterSize;
physicalSize = (U32)fat[dir->head].length * boot->ClusterSize;
}
if (physicalSize < dir->size) {
pwarn("size of %s is %lu, should at most be %lu\n",
Expand Down Expand Up @@ -794,7 +794,7 @@ readDosDirSection(int f, struct bootblock *boot, struct fatEntry *fat,
|| dirent.head >= boot->NumClusters)
pwarn("%s starts with cluster out of range(%lu)\n",
fullpath(&dirent),
dirent.head);
(U32)dirent.head);
else if (fat[dirent.head].next == CLUST_FREE)
pwarn("%s starts with free cluster\n",
fullpath(&dirent));
Expand Down Expand Up @@ -1065,10 +1065,10 @@ reconnect(int dosfs, struct bootblock *boot, struct fatEntry *fat, cl_t head)
boot->NumFiles++;
/* Ensure uniqueness of entry here! XXX */
memset(&d, 0, sizeof d);
(void)snprintf(d.name, sizeof(d.name), "%lu", head);
snprintf(d.name, sizeof(d.name), "%lu", (U32)head);
d.flags = 0;
d.head = head;
d.size = fat[head].length * boot->ClusterSize;
d.size = (U32)fat[head].length * boot->ClusterSize;

memset(p, 0, 32);
memset(p, ' ', 11);
Expand Down
16 changes: 14 additions & 2 deletions elkscmd/fsck_dos/dosfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@

#define DOSBOOTBLOCKSIZE 512

#ifdef ELKS
typedef unsigned short cl_t; /* type holding a cluster number */
#else
typedef u_int32_t cl_t; /* type holding a cluster number */
#endif

/*
* architecture independent description of all the info stored in a
Expand Down Expand Up @@ -89,23 +93,31 @@ struct bootblock {
struct fatEntry {
cl_t next; /* pointer to next cluster */
cl_t head; /* pointer to start of chain */
u_int32_t length; /* number of clusters on chain */
cl_t length; /* number of clusters on chain */
int flags; /* see below */
};

#define CLUST_FREE 0 /* 0 means cluster is free */
#define CLUST_FIRST 2 /* 2 is the minimum valid cluster number */
#ifdef ELKS
#define CLUST_RSRVD 0xfff6UL /* start of reserved clusters */
#define CLUST_BAD 0xfff7UL /* a cluster with a defect */
#define CLUST_EOFS 0xfff8UL /* start of EOF indicators */
#define CLUST_EOF 0xffffUL /* standard value for last cluster */
#define CLUST32_MASK 0x0000UL /* BAD VALUE, not supported on ELKS */
#else
#define CLUST_RSRVD 0xfffffff6UL /* start of reserved clusters */
#define CLUST_BAD 0xfffffff7UL /* a cluster with a defect */
#define CLUST_EOFS 0xfffffff8UL /* start of EOF indicators */
#define CLUST_EOF 0xffffffffUL /* standard value for last cluster */
#define CLUST32_MASK 0x0fffffffUL
#endif

/*
* Masks for cluster values
*/
#define CLUST12_MASK 0xfff
#define CLUST16_MASK 0xffff
#define CLUST32_MASK 0xfffffffUL

#define FAT_USED 1 /* This fat chain is used in a file */

Expand Down
39 changes: 20 additions & 19 deletions elkscmd/fsck_dos/fat.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ checkclnum(struct bootblock *boot, int fat, cl_t cl, cl_t *next)
if (*next < CLUST_FIRST
|| (*next >= boot->NumClusters && *next < CLUST_EOFS)) {
pwarn("Cluster %lu in FAT %d continues with %s cluster number %lu\n",
cl, fat,
(U32)cl, fat,
*next < CLUST_RSRVD ? "out of range" : "reserved",
*next&boot->ClustMask);
(U32)(*next&boot->ClustMask));
if (ask(1, "Truncate")) {
*next = CLUST_EOF;
return FSFATMOD;
Expand Down Expand Up @@ -342,15 +342,15 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
&& *cp2 != CLUST_FREE && *cp2 < CLUST_BAD)
|| (*cp1 > CLUST_BAD && *cp2 > CLUST_BAD)) {
pwarn("Cluster %lu is marked %s with different indicators\n",
cl, rsrvdcltype(*cp1));
(U32)cl, rsrvdcltype(*cp1));
if (ask(1, "Fix")) {
*cp2 = *cp1;
return FSFATMOD;
}
return FSFATAL;
}
pwarn("Cluster %lu is marked %s in FAT 0, %s in FAT %d\n",
cl, rsrvdcltype(*cp1), rsrvdcltype(*cp2), fatnum);
(U32)cl, rsrvdcltype(*cp1), rsrvdcltype(*cp2), fatnum);
if (ask(1, "Use FAT 0's entry")) {
*cp2 = *cp1;
return FSFATMOD;
Expand All @@ -362,7 +362,7 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
return FSFATAL;
}
pwarn("Cluster %lu is marked %s in FAT 0, but continues with cluster %lu in FAT %d\n",
cl, rsrvdcltype(*cp1), *cp2, fatnum);
(U32)cl, rsrvdcltype(*cp1), (U32)*cp2, fatnum);
if (ask(1, "Use continuation from FAT %d", fatnum)) {
*cp1 = *cp2;
return FSFATMOD;
Expand All @@ -375,7 +375,7 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
}
if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
pwarn("Cluster %lu continues with cluster %lu in FAT 0, but is marked %s in FAT %d\n",
cl, *cp1, rsrvdcltype(*cp2), fatnum);
(U32)cl, (U32)*cp1, rsrvdcltype(*cp2), fatnum);
if (ask(1, "Use continuation from FAT 0")) {
*cp2 = *cp1;
return FSFATMOD;
Expand All @@ -387,7 +387,7 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
return FSERROR;
}
pwarn("Cluster %lu continues with cluster %lu in FAT 0, but with cluster %lu in FAT %d\n",
cl, *cp1, *cp2, fatnum);
(U32)cl, (U32)*cp1, (U32)*cp2, fatnum);
if (ask(1, "Use continuation from FAT 0")) {
*cp2 = *cp1;
return FSFATMOD;
Expand Down Expand Up @@ -433,7 +433,7 @@ clearchain(struct bootblock *boot, struct fatEntry *fat, cl_t head)
int
tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *trunc)
{
if (ask(1, "Clear chain starting at %lu", head)) {
if (ask(1, "Clear chain starting at %lu", (U32)head)) {
clearchain(boot, fat, head);
return FSFATMOD;
} else if (ask(1, "Truncate")) {
Expand All @@ -450,7 +450,7 @@ int
checkfat(struct bootblock *boot, struct fatEntry *fat)
{
cl_t head, p, h, n, wdk;
u_int len;
cl_t len;
int ret = 0;
int conf;

Expand All @@ -470,7 +470,7 @@ checkfat(struct bootblock *boot, struct fatEntry *fat)
p = fat[p].next) {
/* we have to check the len, to avoid infinite loop */
if (len > boot->NumClusters) {
printf("detect cluster chain loop: head %lu for p %lu\n", head, p);
printf("detect cluster chain loop: head %lu for p %lu\n", (U32)head, (U32)p);
break;
}

Expand Down Expand Up @@ -506,20 +506,21 @@ checkfat(struct bootblock *boot, struct fatEntry *fat)

if (n == CLUST_FREE || n >= CLUST_RSRVD) {
pwarn("Cluster chain starting at %lu ends with cluster marked %s\n",
head, rsrvdcltype(n));
(U32)head, rsrvdcltype(n));
ret |= tryclear(boot, fat, head, &fat[p].next);
continue;
}
if (n < CLUST_FIRST || n >= boot->NumClusters) {
pwarn("Cluster chain starting at %lu ends with cluster out of range (%lu)\n",
head, n);
(U32)head, (U32)n);
ret |= tryclear(boot, fat, head, &fat[p].next);
continue;
}
pwarn("Cluster chains starting at %lu and %lu are linked at cluster %lu\n",
head, fat[n].head, n);
(U32)head, (U32)fat[n].head, (U32)n);
conf = tryclear(boot, fat, head, &fat[p].next);
if (ask(1, "Clear chain starting at %lu", h = fat[n].head)) {
h = fat[n].head;
if (ask(1, "Clear chain starting at %lu", (U32)h)) {
if (conf == FSERROR) {
/*
* Transfer the common chain to the one not cleared above.
Expand Down Expand Up @@ -674,7 +675,7 @@ checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
continue;

pwarn("Lost cluster chain at cluster %lu\n%ld Cluster(s) lost\n",
head, fat[head].length);
(U32)head, (U32)fat[head].length);
mod |= ret = reconnect(dosfs, boot, fat, head);
if (mod & FSFATAL) {
/* If the reconnect failed, then just clear the chain */
Expand All @@ -695,7 +696,7 @@ checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
ret = 0;
if (boot->FSFree != boot->NumFree) {
pwarn("Free space in FSInfo block (%ld) not correct (%d)\n",
boot->FSFree, boot->NumFree);
(U32)boot->FSFree, boot->NumFree);
if (ask(1, "Fix")) {
boot->FSFree = boot->NumFree;
ret = 1;
Expand All @@ -705,7 +706,7 @@ checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
if (boot->NumFree) {
if ((boot->FSNext >= boot->NumClusters) || (fat[boot->FSNext].next != CLUST_FREE)) {
pwarn("Next free cluster in FSInfo block (%lu) not free\n",
boot->FSNext);
(U32)boot->FSNext);
if (ask(1, "Fix"))
for (head = CLUST_FIRST; head < boot->NumClusters; head++)
if (fat[head].next == CLUST_FREE) {
Expand All @@ -718,13 +719,13 @@ checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)

if (boot->FSNext > boot->NumClusters ) {
pwarn("FSNext block (%ld) not correct NumClusters (%ld)\n",
boot->FSNext, boot->NumClusters);
(U32)boot->FSNext, (U32)boot->NumClusters);
boot->FSNext=CLUST_FIRST; // boot->FSNext can have -1 value.
}

if (boot->NumFree && fat[boot->FSNext].next != CLUST_FREE) {
pwarn("Next free cluster in FSInfo block (%lu) not free\n",
boot->FSNext);
(U32)boot->FSNext);
if (ask(1, "Fix"))
for (head = CLUST_FIRST; head < boot->NumClusters; head++)
if (fat[head].next == CLUST_FREE) {
Expand Down

0 comments on commit 5d82c65

Please sign in to comment.