Skip to content

Commit

Permalink
tweak creat, fewer io for write during cluster links
Browse files Browse the repository at this point in the history
  • Loading branch information
tz committed Jan 26, 2010
1 parent a1b0db3 commit b7b73c3
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 50 deletions.
7 changes: 4 additions & 3 deletions 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. (TESTING) New cluster and link cluster should only do one read then write instead of r w r w.

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 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? typedef int to something?
max file size - if using auto-create log, auto create next log max file size - if using auto-create log, auto create next log


if directory empty allow rmdir if directory empty allow rmdir
check for empty, save . and .. cluster num, delete dir as file, cd .., find . cluster, 0xe5 ent. 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) 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 optional clear new linked clusters (takes time but log will be cleaner on crash
Expand Down
45 changes: 40 additions & 5 deletions fat32lib/creat.c
Expand Up @@ -3,8 +3,7 @@
// sequence number for next auto log file name; // sequence number for next auto log file name;
static u32 nextlog = 0; static u32 nextlog = 0;


unsigned char fntemplate[10] = "FFFFFFFF"; unsigned char newextension[4] = "LOG";
unsigned char extension[4] = "LOG";


static void clearclus(u32 clus) static void clearclus(u32 clus)
{ {
Expand Down Expand Up @@ -49,8 +48,7 @@ static int findemptydirent(u8 * dosname)
if (c[11] == 0x0f) // long name ent if (c[11] == 0x0f) // long name ent
continue; continue;
if (!dosname) { if (!dosname) {

if (c[8] == newextension[0] && c[9] == newextension[1] && c[10] == newextension[2]) {
if (c[8] == extension[0] && c[9] == extension[1] && c[10] == extension[2]) {
u32 thislog = 0; u32 thislog = 0;
u16 j, k; u16 j, k;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
Expand Down Expand Up @@ -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 newdirent(u8 * dosname, u8 attr)
{ {
int r; int r;
Expand All @@ -122,7 +157,7 @@ int newdirent(u8 * dosname, u8 attr)
u32 t = nextlog; u32 t = nextlog;
u8 i = 8, j; u8 i = 8, j;
c += 8; c += 8;
tzmemcpy(c, extension, 3); tzmemcpy(c, newextension, 3);
while (i--) { while (i--) {
j = t & 15; j = t & 15;
#ifndef HEXFN #ifndef HEXFN
Expand Down
4 changes: 2 additions & 2 deletions fat32lib/fat32.h
Expand Up @@ -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 // creates new file or directory (attr with 0x10 set) - changes to dir or ready to write if xero return
// combined creat / mkdir // combined creat / mkdir
// if dosname is NULL (a null pointer) it creates %08X.LOG where the number is 1 greater than any existing // 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 newextension[4]; //= "LOG";
unsigned char fntemplate[10]; //= "FFFFFFFF";
int newdirent(u8 * dosname, u8 attr); int newdirent(u8 * dosname, u8 attr);


// WRITE // WRITE
Expand All @@ -58,6 +57,7 @@ int writenextsect(void); // writes entire secbuf, links, continues at nex
// write out partially written sector // write out partially written sector
void flushbuf(void); 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. // update dirent for writes - mainly file size if changed.past EOF.
// Maxout extends to end of cluster for crash recovery - won't miss anything // Maxout extends to end of cluster for crash recovery - won't miss anything
void syncdirent(u8 maxout); void syncdirent(u8 maxout);
Expand Down
1 change: 0 additions & 1 deletion fat32lib/fat32private.h
Expand Up @@ -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 FAT32EXTERN u8 rmw; // read-mod-write mode, off after new file, append, and truncate


u32 nextclus(u32 clus); u32 nextclus(u32 clus);
u32 getclus(void);


// ATTR X X ARCH DIR VOLID SYS HID RO // 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 // DATE Y-1980, 7 bits : Month 1-12 J=1, 4 bits, Day, 5 bits, 1-31
Expand Down
2 changes: 2 additions & 0 deletions fat32lib/opendir.c
Expand Up @@ -38,6 +38,8 @@ int getdirent(u8 * dosmatch)
entcnt++; // count entries entcnt++; // count entries
// printf( ">%11.11s\n", c ); // printf( ">%11.11s\n", c );
if (!tzfncmp(c, dosmatch)) { if (!tzfncmp(c, dosmatch)) {
// RENAME HERE, memcpy 11 (or 3 for EXT) and writesec(thissector)

// check attributes, etc. // check attributes, etc.
u16 chf; u16 chf;
c += 20; c += 20;
Expand Down
81 changes: 42 additions & 39 deletions fat32lib/write.c
Expand Up @@ -30,69 +30,71 @@ void syncdirent(u8 maxout)
writesec(direntsect); 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 *c;
u8 i;

nextc = nextclus(currclus);
if (nextc < 0xffffff0)
return 0;


newclus = currclus + 1; // from nextclus
while (newclus < fpm.mxcl) { cfatoffst = currclus >> 7;
readsec(fpm.fat0 + (newclus >> 7)); // read sector with cluster
clus = newclus & 127; // index within sector 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]; c = &filesectbuf[clus << 2];
do { do {
get4todw(curr); // get linked cluster get4todw(curr); // get linked cluster
} while (curr && ++clus < 128); } while (curr && ++clus < 128);
newclus &= ~127; nextc &= ~127;
if (clus < 128) if (clus < 128)
break; break;
newclus += 128; nextc += 128;
} }
if (newclus >= fpm.mxcl) if (nextc >= fpm.mxcl) {
return 0; currclus = 0;
newclus += clus; return -1;
}
nextc += clus;
c = &filesectbuf[clus << 2]; c = &filesectbuf[clus << 2];
*c++ = 0xff; *c++ = 0xff;
*c++ = 0xff; *c++ = 0xff;
*c++ = 0xff; *c++ = 0xff;
*c = 0x0f; *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; cfatoffst = currclus >> 7;
byteinsec = 0; if( cfatoffst != nfatoffst ) { // next clus is in diff FAT sector

for (i = 0; i < fpm.nft; i++)
return newclus; writesec(fpm.fat0 + (nextc >> 7) + i * fpm.spf);
} readsec(fpm.fat0 + cfatoffst); // read sector with cluster

static void linkclus()
{
u32 nextc;

nextc = nextclus(currclus);
if (nextc < 0xffffff0)
return;

nextc = getclus();
if (!nextc) {
currclus = 0;
return;
} }
// redundant if alloc and next are in same FAT sector c = &filesectbuf[(currclus & 127) << 2];
readsec(fpm.fat0 + (currclus >> 7)); // read sector with cluster
u8 *c = &filesectbuf[(currclus & 127) << 2];
// should be 0x0fffffff; // should be 0x0fffffff;
*c++ = nextc; *c++ = nextc;
*c++ = nextc >> 8; *c++ = nextc >> 8;
*c++ = nextc >> 16; *c++ = nextc >> 16;
*c = nextc >> 24; *c = nextc >> 24;


u8 i; for (i = 0; i < fpm.nft; i++) // write the linked version out
for (i = 0; i < fpm.nft; i++)
writesec(fpm.fat0 + (currclus >> 7) + i * fpm.spf); writesec(fpm.fat0 + (currclus >> 7) + i * fpm.spf);
currclus = nextc; currclus = nextc;
secinclus = 0;
byteinsec = 0;
return 0;
} }


void flushbuf() void flushbuf()
Expand Down Expand Up @@ -130,7 +132,8 @@ int writenextsect()
#if 0 #if 0
syncdirent(0); syncdirent(0);
#endif #endif
linkclus(); if( linkclus() )
return 1;
secinclus = 0; secinclus = 0;
if (currclus < 2) if (currclus < 2)
return 1; // written, but no more space return 1; // written, but no more space
Expand Down

0 comments on commit b7b73c3

Please sign in to comment.