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
Original file line number Diff line number Diff line change
@@ -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
Expand Down
45 changes: 40 additions & 5 deletions fat32lib/creat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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++) {
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 r;
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions fat32lib/fat32.h
Original file line number Diff line number Diff line change
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
// 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
Expand All @@ -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);
Expand Down
1 change: 0 additions & 1 deletion fat32lib/fat32private.h
Original file line number Diff line number Diff line change
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

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
Expand Down
2 changes: 2 additions & 0 deletions fat32lib/opendir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
81 changes: 42 additions & 39 deletions fat32lib/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit b7b73c3

Please sign in to comment.