diff --git a/fat32lib/TODO b/fat32lib/TODO index 322b91d..35d4d0a 100644 --- a/fat32lib/TODO +++ b/fat32lib/TODO @@ -1,13 +1,14 @@ -newlog naming template, 3 for extension, else max, [0-9A-Z], so FFFFFFFF would do hex, 99999999 would do decimal, ZZZZZZZZ would do all, "FFFF " would limit to 4 chars. - -New cluster and link cluster should only do one read then write instead of r w r w. +(TESTING) New cluster and link cluster should only do one read then write instead of r w r w. dirty buffer flag for RMW - write only when needed, validate RMW fully/properly +Double buffer for sector (fill one while pulling from other). typedef int to something? max file size - if using auto-create log, auto create next log if directory empty allow rmdir check for empty, save . and .. cluster num, delete dir as file, cd .., find . cluster, 0xe5 ent. +newlog naming template, 3 for extension, else max, [0-9A-Z], so FFFFFFFF would do hex, 99999999 would do decimal, ZZZZZZZZ would do all, "FFFF " would limit to 4 chars. + rename (and/or move in tree) (technically writing the directory, chk for dup name) optional clear new linked clusters (takes time but log will be cleaner on crash diff --git a/fat32lib/creat.c b/fat32lib/creat.c index a1b430c..e642c51 100644 --- a/fat32lib/creat.c +++ b/fat32lib/creat.c @@ -3,8 +3,7 @@ // sequence number for next auto log file name; static u32 nextlog = 0; -unsigned char fntemplate[10] = "FFFFFFFF"; -unsigned char extension[4] = "LOG"; +unsigned char newextension[4] = "LOG"; static void clearclus(u32 clus) { @@ -49,8 +48,7 @@ static int findemptydirent(u8 * dosname) if (c[11] == 0x0f) // long name ent continue; if (!dosname) { - - if (c[8] == extension[0] && c[9] == extension[1] && c[10] == extension[2]) { + if (c[8] == newextension[0] && c[9] == newextension[1] && c[10] == newextension[2]) { u32 thislog = 0; u16 j, k; for (j = 0; j < 8; j++) { @@ -97,6 +95,43 @@ static void setdirent(u8 * c, u8 attr, u32 clus) } } +static u32 getclus() +{ + u32 clus = 0, newclus, curr = 1; + u8 *c; + + newclus = currclus + 1; + while (newclus < fpm.mxcl) { + readsec(fpm.fat0 + (newclus >> 7)); // read sector with cluster + clus = newclus & 127; // index within sector + c = &filesectbuf[clus << 2]; + do { + get4todw(curr); // get linked cluster + } while (curr && ++clus < 128); + newclus &= ~127; + if (clus < 128) + break; + newclus += 128; + } + if (newclus >= fpm.mxcl) + return 0; + newclus += clus; + c = &filesectbuf[clus << 2]; + *c++ = 0xff; + *c++ = 0xff; + *c++ = 0xff; + *c = 0x0f; + // can merge link here for that case - saves extra read and write if in same clus + u8 i; + for (i = 0; i < fpm.nft; i++) + writesec(fpm.fat0 + (newclus >> 7) + i * fpm.spf); + + secinclus = 0; + byteinsec = 0; + + return newclus; +} + int newdirent(u8 * dosname, u8 attr) { int r; @@ -122,7 +157,7 @@ int newdirent(u8 * dosname, u8 attr) u32 t = nextlog; u8 i = 8, j; c += 8; - tzmemcpy(c, extension, 3); + tzmemcpy(c, newextension, 3); while (i--) { j = t & 15; #ifndef HEXFN diff --git a/fat32lib/fat32.h b/fat32lib/fat32.h index e954531..7f582f7 100644 --- a/fat32lib/fat32.h +++ b/fat32lib/fat32.h @@ -42,8 +42,7 @@ int getdirent(u8 * dosmatch); // creates new file or directory (attr with 0x10 set) - changes to dir or ready to write if xero return // combined creat / mkdir // if dosname is NULL (a null pointer) it creates %08X.LOG where the number is 1 greater than any existing -unsigned char extension[4]; //= "LOG"; -unsigned char fntemplate[10]; //= "FFFFFFFF"; +unsigned char newextension[4]; //= "LOG"; int newdirent(u8 * dosname, u8 attr); // WRITE @@ -58,6 +57,7 @@ int writenextsect(void); // writes entire secbuf, links, continues at nex // write out partially written sector void flushbuf(void); +// DO flushbuf BEFORE CALLING THIS IF THE BUFFER IS NOT FLUSHED // update dirent for writes - mainly file size if changed.past EOF. // Maxout extends to end of cluster for crash recovery - won't miss anything void syncdirent(u8 maxout); diff --git a/fat32lib/fat32private.h b/fat32lib/fat32private.h index 867baad..9d78aab 100644 --- a/fat32lib/fat32private.h +++ b/fat32lib/fat32private.h @@ -62,7 +62,6 @@ FAT32EXTERN u16 byteinsec; //which byte in the sector FAT32EXTERN u8 rmw; // read-mod-write mode, off after new file, append, and truncate u32 nextclus(u32 clus); -u32 getclus(void); // ATTR X X ARCH DIR VOLID SYS HID RO // DATE Y-1980, 7 bits : Month 1-12 J=1, 4 bits, Day, 5 bits, 1-31 diff --git a/fat32lib/opendir.c b/fat32lib/opendir.c index a9510da..f5a6894 100644 --- a/fat32lib/opendir.c +++ b/fat32lib/opendir.c @@ -38,6 +38,8 @@ int getdirent(u8 * dosmatch) entcnt++; // count entries // printf( ">%11.11s\n", c ); if (!tzfncmp(c, dosmatch)) { + // RENAME HERE, memcpy 11 (or 3 for EXT) and writesec(thissector) + // check attributes, etc. u16 chf; c += 20; diff --git a/fat32lib/write.c b/fat32lib/write.c index 57bc2bd..1a62691 100644 --- a/fat32lib/write.c +++ b/fat32lib/write.c @@ -30,69 +30,71 @@ void syncdirent(u8 maxout) writesec(direntsect); } -u32 getclus() +// this allocates and links in a new cluseter. +// inlined getclus so for in-sector, it iw r w(w fat copy 2) except where the link crosses sectors +// whire it is r0 ... rN wN(wN) r0 w0(w0). +static int linkclus() { - u32 clus = 0, newclus, curr = 1; + u32 nextc; + u32 clus = 0, curr = 1; + u32 cfatoffst, nfatoffst; u8 *c; + u8 i; + + nextc = nextclus(currclus); + if (nextc < 0xffffff0) + return 0; - newclus = currclus + 1; - while (newclus < fpm.mxcl) { - readsec(fpm.fat0 + (newclus >> 7)); // read sector with cluster - clus = newclus & 127; // index within sector + // from nextclus + cfatoffst = currclus >> 7; + + nextc = currclus + 1; + while (nextc < fpm.mxcl) { + nfatoffst = nextc >> 7; + if( nfatoffst != cfatoffst ) { + readsec(fpm.fat0 + (nextc >> 7)); // read sector with cluster + cfatoffst = nfatoffst; + } + clus = nextc & 127; // index within sector c = &filesectbuf[clus << 2]; do { get4todw(curr); // get linked cluster } while (curr && ++clus < 128); - newclus &= ~127; + nextc &= ~127; if (clus < 128) break; - newclus += 128; + nextc += 128; } - if (newclus >= fpm.mxcl) - return 0; - newclus += clus; + if (nextc >= fpm.mxcl) { + currclus = 0; + return -1; + } + nextc += clus; c = &filesectbuf[clus << 2]; *c++ = 0xff; *c++ = 0xff; *c++ = 0xff; *c = 0x0f; - // can merge link here for that case - saves extra read and write if in same clus - u8 i; - for (i = 0; i < fpm.nft; i++) - writesec(fpm.fat0 + (newclus >> 7) + i * fpm.spf); - secinclus = 0; - byteinsec = 0; - - return newclus; -} - -static void linkclus() -{ - u32 nextc; - - nextc = nextclus(currclus); - if (nextc < 0xffffff0) - return; - - nextc = getclus(); - if (!nextc) { - currclus = 0; - return; + cfatoffst = currclus >> 7; + if( cfatoffst != nfatoffst ) { // next clus is in diff FAT sector + for (i = 0; i < fpm.nft; i++) + writesec(fpm.fat0 + (nextc >> 7) + i * fpm.spf); + readsec(fpm.fat0 + cfatoffst); // read sector with cluster } - // redundant if alloc and next are in same FAT sector - readsec(fpm.fat0 + (currclus >> 7)); // read sector with cluster - u8 *c = &filesectbuf[(currclus & 127) << 2]; + c = &filesectbuf[(currclus & 127) << 2]; // should be 0x0fffffff; *c++ = nextc; *c++ = nextc >> 8; *c++ = nextc >> 16; *c = nextc >> 24; - u8 i; - for (i = 0; i < fpm.nft; i++) + for (i = 0; i < fpm.nft; i++) // write the linked version out writesec(fpm.fat0 + (currclus >> 7) + i * fpm.spf); currclus = nextc; + secinclus = 0; + byteinsec = 0; + return 0; } void flushbuf() @@ -130,7 +132,8 @@ int writenextsect() #if 0 syncdirent(0); #endif - linkclus(); + if( linkclus() ) + return 1; secinclus = 0; if (currclus < 2) return 1; // written, but no more space