revert changes for fat32 support that appear not to be working correctly. Reference: /n/atom/patch/applied2013/revertfmtfat32 Date: Wed Jun 19 22:20:56 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/disk/format.c Wed Jun 19 22:20:36 2013 +++ /sys/src/cmd/disk/format.c Wed Jun 19 22:20:36 2013 @@ -4,7 +4,7 @@ #include /* - * disk types + * disk types (all MFM encoding) */ typedef struct Type Type; struct Type @@ -45,55 +45,25 @@ uchar nheads[2]; uchar nhidden[4]; uchar bigvolsize[4]; - union{ - struct{ - uchar driveno16; - uchar reserved16; - uchar bootsig; - uchar volid[4]; - uchar label[11]; - uchar type[8]; - }; - struct{ - uchar fatsize32[4]; - uchar extflags[2]; - uchar extver[2]; - uchar rootclust[4]; - uchar fsinfo[2]; - uchar bootblk[2]; - uchar reserved32[12]; - uchar driveno32; - }; - }; + uchar driveno; + uchar reserved0; + uchar bootsig; + uchar volid[4]; + uchar label[11]; + uchar type[8]; }; #define PUTSHORT(p, v) { (p)[1] = (v)>>8; (p)[0] = (v); } #define PUTLONG(p, v) { PUTSHORT((p), (v)); PUTSHORT((p)+2, (v)>>16); } #define GETSHORT(p) (((p)[1]<<8)|(p)[0]) #define GETLONG(p) (((ulong)GETSHORT(p+2)<<16)|(ulong)GETSHORT(p)) -typedef struct Fsinfo Fsinfo; -struct Fsinfo -{ - uchar siga[4]; /* 0x41615252 RRaA */ - uchar res[480]; - uchar sigb[4]; /* 0x61417272 rrAa */ - uchar free[4]; - uchar nxtfree[4]; - uchar res1[12]; - uchar sigc[4]; -}; - typedef struct Dosdir Dosdir; struct Dosdir { uchar name[8]; uchar ext[3]; uchar attr; - uchar reserved[1]; - uchar ctime[3]; /* creation time */ - uchar cdate[2]; /* creation date */ - uchar adate[2]; /* last access date */ - uchar hstart[2]; /* high bits of start for fat32 */ + uchar reserved[10]; uchar time[2]; uchar date[2]; uchar start[2]; @@ -135,26 +105,18 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA, }; -Fsinfo fsinfo = -{ -.siga = {'R', 'R', 'a', 'A', }, -.sigb = {'r', 'r', 'A', 'a', }, -.free = {0xff, 0xff, 0xff, 0xff, }, -.nxtfree = {0xff, 0xff, 0xff, 0xff, }, -.sigc = {0x00, 0x00, 0x55, 0xaa, }, -}; - char *dev; int clustersize; uchar *fat; /* the fat */ int fatbits; -uint fatsecs; -uint fatlast; /* last cluster allocated */ -uvlong clusters; -uvlong volsecs; +int fatsecs; +int fatlast; /* last cluster allocated */ +int clusters; +int fatsecs; +vlong volsecs; uchar *root; /* first block of root */ int rootsecs; -uvlong rootfiles; +int rootfiles; int rootnext; int nresrv = 1; int chatty; @@ -180,8 +142,6 @@ void addrname(uchar*, Dir*, char*, ulong); void sanitycheck(Disk*); -#define chat(...) if(chatty) fprint(2, __VA_ARGS__); else {} - void usage(void) { @@ -204,7 +164,6 @@ remove(file); exits(err); } -#pragma varargck argpos fatal 1 void main(int argc, char **argv) @@ -361,19 +320,16 @@ * 0x80 is the first fixed disk, 0x81 the next, etc. * We map sdC0=0x80, sdC1=0x81, sdD0=0x82, sdD1=0x83 */ -void -putdriveno(Disk *disk, uchar media, uchar *driveno) +int +getdriveno(Disk *disk) { char buf[64], *p; - if(media != 0xF8){ - *driveno = 0; - return; - } - buf[0] = 0; - *driveno = 0x80; /* first hard disk */ - if(disk->type != Tsd && fd2path(disk->fd, buf, sizeof(buf)) < 0) - buf[0] = 0; + if(disk->type != Tsd) + return 0x80; /* first hard disk */ + + if(fd2path(disk->fd, buf, sizeof(buf)) < 0) + return 0x80; /* * The name is of the format #SsdC0/foo @@ -387,7 +343,9 @@ for(p=buf; *p; p++) if(p[0] == 's' && p[1] == 'd' && (p[2]=='C' || p[2]=='D') && (p[3]=='0' || p[3]=='1')) - *driveno = 0x80 + (p[2]-'C')*2 + (p[3]-'0'); + return 0x80 + (p[2]-'C')*2 + (p[3]-'0'); + + return 0x80; } long @@ -406,60 +364,6 @@ return tot; } -int -pwr2chk(uvlong u, uvlong max) -{ - uvlong i; - - if(u > max) - return -1; - for(i = 0; i < 8*sizeof i; i++) - if((u & ~(1ull<secsize; - - /* fat 1.03 restrictions */ - if(pwr2chk(secsize, 4096) || secsize < 512) - fatal("illegal sector size"); - if(secsize * clustersize > 32*1024) - fatal("secsize * clustersize must be <= 32k"); - if(pwr2chk(clustersize, 64) == -1) - fatal("illegal clustersize"); - if(nresrv == 0) - fatal("nresrv may not be 0"); - - if(xflag) /* botch; other xflag will have exited */ - return; - if(clustersize > 32) - fatal("clustersize should be <= 32; use -x to allow"); -} - -#define Rskip nresrv - -void -wfsinfo(Disk *d, Dosboot *b, uvlong secsize, int bits) -{ - uvlong off; - - if(bits != 32) - return; - PUTLONG(fsinfo.free, clusters - fatlast - 1); - PUTLONG(fsinfo.nxtfree, fatlast+1); - off = GETSHORT(b->fsinfo); - off *= secsize; - chat("fsinfo at %lld size %d\n", off, sizeof fsinfo); - if(pwrite(d->wfd, &fsinfo, sizeof fsinfo, off) != sizeof fsinfo) - fatal("pwrite fsinfo: %r"); -} - void dosfs(int dofat, int dopbs, Disk *disk, char *label, int argc, char *argv[], int commit) { @@ -467,9 +371,9 @@ Dosboot *b; uchar *buf, *pbsbuf, *p; Dir *d; - int i, npbs, n, sysfd; + int i, data, newclusters, npbs, n, sysfd; ulong x; - uvlong length, data, secsize, newclusters, bits, rootclust; + vlong length, secsize; if(dofat == 0 && dopbs == 0) return; @@ -490,15 +394,13 @@ fatal("cannot format fat with type %s: geometry unknown\n", type); if(fflag){ - disk->size = (uvlong)t->bytes*t->sectors*t->heads*t->tracks; + disk->size = t->bytes*t->sectors*t->heads*t->tracks; disk->secsize = t->bytes; disk->secs = disk->size / disk->secsize; } - fatchecks(disk); secsize = disk->secsize; length = disk->size; - chat("t size %lld length %lld\n", secsize, length); buf = malloc(secsize); if(buf == 0) @@ -590,9 +492,8 @@ * try both. what a crock. */ fatbits = 12; - volsecs = length/secsize; - chat("volsecs %lld\n", volsecs); Tryagain: + volsecs = length/secsize; /* * here's a crock inside a crock. even having fixed fatbits, * the number of fat sectors depends on the number of clusters, @@ -601,39 +502,24 @@ */ clusters = 0; for(i=0;; i++){ - bits = fatbits*clusters; - fatsecs = (bits + 8*secsize - 1)/(8ull*secsize); + fatsecs = (fatbits*clusters + 8*secsize - 1)/(8*secsize); rootsecs = volsecs/200; - if(rootsecs*secsize > 10240*512) - rootsecs = 10240*512/secsize; - switch(fatbits){ - case 12: - rootfiles = rootsecs * (secsize/sizeof(Dosdir)); - if(rootfiles > 512){ - rootfiles = 512; - rootsecs = rootfiles/(secsize/sizeof(Dosdir)); - } - break; - case 16: + rootfiles = rootsecs * (secsize/sizeof(Dosdir)); + if(rootfiles > 512){ rootfiles = 512; - break; - case 32: - rootfiles = rootsecs * (secsize/sizeof(Dosdir)); - break; + rootsecs = rootfiles/(secsize/sizeof(Dosdir)); } - /* probablly bogus for fat32; p. 32 */ data = nresrv + 2*fatsecs + (rootfiles*sizeof(Dosdir) + secsize-1)/secsize; newclusters = 2 + (volsecs - data)/clustersize; if(newclusters == clusters) break; clusters = newclusters; if(i > 10) - fatal("can't decide how many clusters to use (%lld? %lld?)", clusters, newclusters); - // chat("clusters %lld\n", clusters); + fatal("can't decide how many clusters to use (%d? %d?)", clusters, newclusters); +if(chatty) print("clusters %d\n", clusters); } - chat("try %d fatbits => %lld clusters of %d\n", fatbits, clusters, clustersize); - chat("\t" "rootfiles %lld rootsecs %d\n", rootfiles, rootsecs); +if(chatty) print("try %d fatbits => %d clusters of %d\n", fatbits, clusters, clustersize); switch(fatbits){ case 12: if(clusters >= 4087){ @@ -642,57 +528,40 @@ } break; case 16: - if(clusters >= 65527){ - fatbits = 32; - nresrv = 32; - goto Tryagain; - } - case 32: - if(clusters >= 1<<28) - fatal("disk too big; try -c"); + if(clusters >= 65527) + fatal("disk too big; implement fat32"); break; } PUTSHORT(b->sectsize, secsize); b->clustsize = clustersize; PUTSHORT(b->nresrv, nresrv); b->nfats = 2; - if(fatbits != 32) - PUTSHORT(b->rootsize, rootfiles); + PUTSHORT(b->rootsize, rootfiles); if(volsecs < (1<<16)) PUTSHORT(b->volsize, volsecs); b->mediadesc = t->media; - if(fatbits != 32) - PUTSHORT(b->fatsize, fatsecs); + PUTSHORT(b->fatsize, fatsecs); PUTSHORT(b->trksize, t->sectors); PUTSHORT(b->nheads, t->heads); PUTLONG(b->nhidden, disk->offset); - if(volsecs >= (1<<16)) - PUTLONG(b->bigvolsize, volsecs); + PUTLONG(b->bigvolsize, volsecs); /* * Extended BIOS Parameter Block. */ - if(fatbits == 32){ - chat("fatsize %ud\n", fatsecs); - rootclust = 2; - PUTLONG(b->fatsize32, fatsecs); - PUTLONG(b->rootclust, rootclust); - PUTSHORT(b->fsinfo, 1); - PUTSHORT(b->bootblk, 6); - putdriveno(disk, t->media, &b->driveno32); - chat("driveno = %ux\n", b->driveno32); - }else{ - rootclust = 0; - putdriveno(disk, t->media, &b->driveno16); - chat("driveno = %ux\n", b->driveno16); - b->bootsig = 0x29; - x = disk->offset + b->nfats*fatsecs + nresrv; - PUTLONG(b->volid, x); - chat("volid = %lux %lux\n", x, GETLONG(b->volid)); - memmove(b->label, label, sizeof(b->label)); - sprint(r, "FAT%d ", fatbits); /* informational only */ - memmove(b->type, r, sizeof(b->type)); - } + if(t->media == 0xF8) + b->driveno = getdriveno(disk); + else + b->driveno = 0; +if(chatty) print("driveno = %ux\n", b->driveno); + + b->bootsig = 0x29; + x = disk->offset + b->nfats*fatsecs + nresrv; + PUTLONG(b->volid, x); +if(chatty) print("volid = %lux %lux\n", x, GETLONG(b->volid)); + memmove(b->label, label, sizeof(b->label)); + sprint(r, "FAT%d ", fatbits); + memmove(b->type, r, sizeof(b->type)); } buf[secsize-2] = 0x55; @@ -705,20 +574,20 @@ fatal("writing boot sector: %r"); } + free(buf); + /* * If we were only called to write the PBS, leave now. */ - if(dofat == 0){ - free(b); + if(dofat == 0) return; - } /* * allocate an in memory fat */ - if(seek(disk->wfd, Rskip*secsize, 0) < 0) + if(seek(disk->wfd, nresrv*secsize, 0) < 0) fatal("seek to fat: %r\n"); - chat("fat @%lluX\n", seek(disk->wfd, 0, 1)); +if(chatty) print("fat @%lluX\n", seek(disk->wfd, 0, 1)); fat = malloc(fatsecs*secsize); if(fat == 0) fatal("out of memory"); @@ -726,13 +595,12 @@ fat[0] = t->media; fat[1] = 0xff; fat[2] = 0xff; - if(fatbits >= 16) + if(fatbits == 16) fat[3] = 0xff; fatlast = 1; if(seek(disk->wfd, 2*fatsecs*secsize, 1) < 0) /* 2 fats */ fatal("seek to root: %r"); - chat("root @%lluX\n", seek(disk->wfd, 0LL, 1)); -chat("fsinfo %d %.2ux %.2ux\n", GETSHORT(b->fsinfo), b->fsinfo[0], b->fsinfo[1]); +if(chatty) print("root @%lluX\n", seek(disk->wfd, 0LL, 1)); /* * allocate an in memory root @@ -743,7 +611,7 @@ memset(root, 0, rootsecs*secsize); if(seek(disk->wfd, rootsecs*secsize, 1) < 0) /* rootsecs */ fatal("seek to files: %r"); - chat("files @%lluX\n", seek(disk->wfd, 0LL, 1)); +if(chatty) print("files @%lluX\n", seek(disk->wfd, 0LL, 1)); /* * Now positioned at the Files Area. @@ -751,7 +619,7 @@ * them and write out. */ for(p = root; argc > 0; argc--, argv++, p += sizeof(Dosdir)){ - if(p >= root+rootsecs*secsize) + if(p >= (root+(rootsecs*secsize))) fatal("too many files in root"); /* * Open the file and get its length. @@ -761,7 +629,7 @@ if((d = dirfstat(sysfd)) == nil) fatal("stat %s: %r", *argv); if(d->length > 0xFFFFFFFFU) - fatal("file %s too big %lld\n", *argv, d->length); + fatal("file %s too big\n", *argv, d->length); if(commit) print("Adding file %s, length %lld\n", *argv, d->length); @@ -782,7 +650,7 @@ if(readn(sysfd, buf, d->length) != d->length) fatal("read %s: %r", *argv); memset(buf+d->length, 0, length-d->length); - chat("%s @%lluX\n", d->name, seek(disk->wfd, 0LL, 1)); +if(chatty) print("%s @%lluX\n", d->name, seek(disk->wfd, 0LL, 1)); if(commit && writen(disk->wfd, buf, length) != length) fatal("write %s: %r", *argv); free(buf); @@ -808,7 +676,7 @@ /* * Add the filename to the root. */ - chat("add %s at clust %lux\n", d->name, x); +fprint(2, "add %s at clust %lux\n", d->name, x); addrname(p, d, *argv, x); free(d); } @@ -817,22 +685,16 @@ * write the fats and root */ if(commit) { - chat("rootclust %lld clustersize %d nresrv %d Rskip %ds = %lld\n", - rootclust, clustersize, nresrv, Rskip, Rskip*secsize); - if(seek(disk->wfd, Rskip*secsize, 0) < 0) + if(seek(disk->wfd, nresrv*secsize, 0) < 0) fatal("seek to fat #1: %r"); - chat("fat#1 at %lld %lld sz \n", seek(disk->wfd, 0, 1), seek(disk->wfd, 0, 1) / secsize); - if(writen(disk->wfd, fat, fatsecs*secsize) < 0) + if(write(disk->wfd, fat, fatsecs*secsize) < 0) fatal("writing fat #1: %r"); - chat("fat#2 at %lld %lld\n", seek(disk->wfd, 0, 1), seek(disk->wfd, 0, 1) / secsize); - if(writen(disk->wfd, fat, fatsecs*secsize) < 0) + if(write(disk->wfd, fat, fatsecs*secsize) < 0) fatal("writing fat #2: %r"); - if(writen(disk->wfd, root, rootsecs*secsize) < 0) + if(write(disk->wfd, root, rootsecs*secsize) < 0) fatal("writing root: %r"); - wfsinfo(disk, b, secsize, fatbits); } - free(b); free(fat); free(root); } @@ -846,27 +708,21 @@ ulong o, x; if(flag != Sof){ - x = flag == Eof? 0xffffffff : fatlast+1; + x = (flag == Eof) ? 0xffff : (fatlast+1); if(fatbits == 12){ x &= 0xfff; o = (3*fatlast)/2; if(fatlast & 1){ - fat[o] = fat[o]&0x0f | x<<4; - fat[o+1] = x>>4; + fat[o] = (fat[o]&0x0f) | (x<<4); + fat[o+1] = (x>>4); } else { fat[o] = x; - fat[o+1] = fat[o+1]&0xf0 | x>>8&0x0f; + fat[o+1] = (fat[o+1]&0xf0) | ((x>>8) & 0x0F); } - } else if(fatbits == 16) { + } else { o = 2*fatlast; fat[o] = x; fat[o+1] = x>>8; - } else { - if(flag != Eof) - x += 2*fatsecs + nresrv; -chat("DAMN x %ld\n", x); - o = 4*fatlast; - PUTLONG(fat+o, x); } } @@ -875,7 +731,7 @@ else{ ++fatlast; if(fatlast >= clusters) - sysfatal("data does not fit on disk (%d %lld)", fatlast, clusters); + sysfatal("data does not fit on disk (%d %d)", fatlast, clusters); return fatlast; } } @@ -902,17 +758,17 @@ } void -puttime(uchar *tim, uchar *date) +puttime(Dosdir *d) { Tm *t = localtime(time(0)); ushort x; - if(tim != nil){ - x = t->hour<<11 | t->min<<5 | t->sec>>1; - PUTSHORT(tim, x); - } - x = t->year-80<<9 | t->mon+1<<5 | t->mday; - PUTSHORT(date, x); + x = (t->hour<<11) | (t->min<<5) | (t->sec>>1); + d->time[0] = x; + d->time[1] = x>>8; + x = ((t->year-80)<<9) | ((t->mon+1)<<5) | t->mday; + d->date[0] = x; + d->date[1] = x>>8; } void @@ -933,12 +789,11 @@ d->attr = DSYSTEM; else d->attr = 0; - puttime(d->time, d->date); - puttime(d->ctime, d->cdate); - puttime(nil, d->adate); - - PUTSHORT(d->start, start); - start >>= 16; - PUTSHORT(d->hstart, start); - PUTLONG(d->length, dir->length); + puttime(d); + d->start[0] = start; + d->start[1] = start>>8; + d->length[0] = dir->length; + d->length[1] = dir->length>>8; + d->length[2] = dir->length>>16; + d->length[3] = dir->length>>24; }