Rockbox.org home
release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



Rockbox mail archive

Subject: disk write code - another bug
From: Greg Haerr (greg_at_censoft.com)
Date: 2002-11-09


Bjorn,
    There's another bug in cache_fat_sectors, seen only when
files > 4095 clusters are in use in the FAT table. The cache_fat_sectors
routine doesn't write out a second copy of the dirty sector to
FAT #2 if two FATs are in use. This of course gets the FAT #2
to be out-of-sync and dosfsck complains.

Following is a working version. I'm going to convert this to the buffer-
cached routines over the weekend and see how much more code
I can clean up (this will be done after I get the multi-sector read/write
stuff working)

I also moved the constant use of fat_cache[cache_index] into a
pointer variable, this saves a lot of code generated.

static void *cache_fat_sector(int fatsector)
{
    int secnum = fatsector + fat_bpb.bpb_rsvdseccnt;
    int cache_index = secnum & FAT_CACHE_MASK;
    struct fat_cache_entry *fce = &fat_cache[cache_index];
    unsigned char *sectorbuf = &fat_cache_sectors[cache_index][0];

    /* Delete the cache entry if it isn't the sector we want */
    if(fce->inuse && fce->secnum != secnum)
    {
        /* Write back if it is dirty */
        if(fce->dirty)
        {
            if(ata_write_sectors(fce->secnum+fat_bpb.startsector, 1, sectorbuf))
            {
                panicf("cache_fat_sector() - Could not write sector %d\n",
                       secnum);
            }
            if(fat_bpb.bpb_numfats > 1)
            {
                /* Write to the second FAT */
                if(ata_write_sectors(fce->secnum+fat_bpb.fatsize, 1, sectorbuf))
                {
                    panicf("cache_fat_sector() - Could not write sector %d\n",
                           secnum + fat_bpb.fatsize);
                }
            }
        }
        fce->secnum = 8; /* Normally an unused sector */
        fce->dirty = false;
        fce->inuse = false;
    }

    /* Load the sector if it is not cached */
    if(!fce->inuse)
    {
        if(ata_read_sectors(secnum + fat_bpb.startsector,1,
                            sectorbuf))
        {
            DEBUGF( "cache_fat_sector() - Could not read sector %d\n", secnum);
            return NULL;
        }
        fce->inuse = true;
        fce->secnum = secnum;
    }
    return sectorbuf;
}

Regards,

Greg



Page was last modified "Jan 10 2012" The Rockbox Crew
aaa