1
0
Fork 0
forked from len0rd/rockbox

iPod Classic CE-ATA Support (Part 2 of 4: Remove on-stack sector buffers, and replace them with a single statically allocated sector buffer that's arbitrated amongst users)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29445 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sparmann 2011-02-27 22:44:54 +00:00
parent 751303c2ac
commit 1b5e31ed43
5 changed files with 141 additions and 28 deletions

View file

@ -67,7 +67,6 @@ int disk_sector_multiplier = 1;
struct partinfo* disk_init(IF_MD_NONVOID(int drive)) struct partinfo* disk_init(IF_MD_NONVOID(int drive))
{ {
int i; int i;
unsigned char sector[SECTOR_SIZE];
#ifdef HAVE_MULTIDRIVE #ifdef HAVE_MULTIDRIVE
/* For each drive, start at a different position, in order not to destroy /* For each drive, start at a different position, in order not to destroy
the first entry of drive 0. the first entry of drive 0.
@ -81,10 +80,12 @@ struct partinfo* disk_init(IF_MD_NONVOID(int drive))
(void)drive; (void)drive;
#endif #endif
unsigned char* sector = fat_get_sector_buffer();
storage_read_sectors(IF_MD2(drive,) 0,1, sector); storage_read_sectors(IF_MD2(drive,) 0,1, sector);
/* check that the boot sector is initialized */ /* check that the boot sector is initialized */
if ( (sector[510] != 0x55) || if ( (sector[510] != 0x55) ||
(sector[511] != 0xaa)) { (sector[511] != 0xaa)) {
fat_release_sector_buffer();
DEBUGF("Bad boot sector signature\n"); DEBUGF("Bad boot sector signature\n");
return NULL; return NULL;
} }
@ -104,6 +105,7 @@ struct partinfo* disk_init(IF_MD_NONVOID(int drive))
/* not handled yet */ /* not handled yet */
} }
} }
fat_release_sector_buffer();
return pinfo; return pinfo;
} }

View file

@ -214,6 +214,9 @@ struct fat_cache_entry
static char fat_cache_sectors[FAT_CACHE_SIZE][SECTOR_SIZE] CACHEALIGN_ATTR; static char fat_cache_sectors[FAT_CACHE_SIZE][SECTOR_SIZE] CACHEALIGN_ATTR;
static struct fat_cache_entry fat_cache[FAT_CACHE_SIZE]; static struct fat_cache_entry fat_cache[FAT_CACHE_SIZE];
static struct mutex cache_mutex SHAREDBSS_ATTR; static struct mutex cache_mutex SHAREDBSS_ATTR;
static struct mutex tempbuf_mutex;
static char fat_tempbuf[SECTOR_SIZE] CACHEALIGN_ATTR;
static bool tempbuf_locked;
#if defined(HAVE_HOTSWAP) && !(CONFIG_STORAGE & STORAGE_MMC) /* A better condition ?? */ #if defined(HAVE_HOTSWAP) && !(CONFIG_STORAGE & STORAGE_MMC) /* A better condition ?? */
void fat_lock(void) void fat_lock(void)
@ -269,6 +272,8 @@ void fat_init(void)
{ {
initialized = true; initialized = true;
mutex_init(&cache_mutex); mutex_init(&cache_mutex);
mutex_init(&tempbuf_mutex);
tempbuf_locked = false;
} }
#ifdef HAVE_PRIORITY_SCHEDULING #ifdef HAVE_PRIORITY_SCHEDULING
@ -304,7 +309,6 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
const int volume = 0; const int volume = 0;
#endif #endif
struct bpb* fat_bpb = &fat_bpbs[volume]; struct bpb* fat_bpb = &fat_bpbs[volume];
unsigned char buf[SECTOR_SIZE];
int rc; int rc;
int secmult; int secmult;
long datasec; long datasec;
@ -312,10 +316,12 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
int rootdirsectors; int rootdirsectors;
#endif #endif
unsigned char* buf = fat_get_sector_buffer();
/* Read the sector */ /* Read the sector */
rc = storage_read_sectors(IF_MD2(drive,) startsector,1,buf); rc = storage_read_sectors(IF_MD2(drive,) startsector,1,buf);
if(rc) if(rc)
{ {
fat_release_sector_buffer();
DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc); DEBUGF( "fat_mount() - Couldn't read BPB (error code %d)\n", rc);
return rc * 10 - 1; return rc * 10 - 1;
} }
@ -354,7 +360,10 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
#ifdef HAVE_FAT16SUPPORT #ifdef HAVE_FAT16SUPPORT
fat_bpb->bpb_rootentcnt = BYTES2INT16(buf,BPB_ROOTENTCNT); fat_bpb->bpb_rootentcnt = BYTES2INT16(buf,BPB_ROOTENTCNT);
if (!fat_bpb->bpb_bytspersec) if (!fat_bpb->bpb_bytspersec)
{
fat_release_sector_buffer();
return -2; return -2;
}
rootdirsectors = secmult * ((fat_bpb->bpb_rootentcnt * DIR_ENTRY_SIZE rootdirsectors = secmult * ((fat_bpb->bpb_rootentcnt * DIR_ENTRY_SIZE
+ fat_bpb->bpb_bytspersec - 1) / fat_bpb->bpb_bytspersec); + fat_bpb->bpb_bytspersec - 1) / fat_bpb->bpb_bytspersec);
#endif /* #ifdef HAVE_FAT16SUPPORT */ #endif /* #ifdef HAVE_FAT16SUPPORT */
@ -370,7 +379,10 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
if (fat_bpb->bpb_secperclus) if (fat_bpb->bpb_secperclus)
fat_bpb->dataclusters = datasec / fat_bpb->bpb_secperclus; fat_bpb->dataclusters = datasec / fat_bpb->bpb_secperclus;
else else
{
fat_release_sector_buffer();
return -2; return -2;
}
#ifdef TEST_FAT #ifdef TEST_FAT
/* /*
@ -386,10 +398,12 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
fat_bpb->is_fat16 = true; fat_bpb->is_fat16 = true;
if (fat_bpb->dataclusters < 4085) if (fat_bpb->dataclusters < 4085)
{ /* FAT12 */ { /* FAT12 */
fat_release_sector_buffer();
DEBUGF("This is FAT12. Go away!\n"); DEBUGF("This is FAT12. Go away!\n");
return -2; return -2;
} }
#else /* #ifdef HAVE_FAT16SUPPORT */ #else /* #ifdef HAVE_FAT16SUPPORT */
fat_release_sector_buffer();
DEBUGF("This is not FAT32. Go away!\n"); DEBUGF("This is not FAT32. Go away!\n");
return -2; return -2;
#endif /* #ifndef HAVE_FAT16SUPPORT */ #endif /* #ifndef HAVE_FAT16SUPPORT */
@ -421,6 +435,7 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
rc = bpb_is_sane(IF_MV(fat_bpb)); rc = bpb_is_sane(IF_MV(fat_bpb));
if (rc < 0) if (rc < 0)
{ {
fat_release_sector_buffer();
DEBUGF( "fat_mount() - BPB is not sane\n"); DEBUGF( "fat_mount() - BPB is not sane\n");
return rc * 10 - 3; return rc * 10 - 3;
} }
@ -439,15 +454,32 @@ static int fat_mount_internal(IF_MV2(int volume,) IF_MD2(int drive,) long starts
startsector + fat_bpb->bpb_fsinfo, 1, buf); startsector + fat_bpb->bpb_fsinfo, 1, buf);
if (rc < 0) if (rc < 0)
{ {
fat_release_sector_buffer();
DEBUGF( "fat_mount() - Couldn't read FSInfo (error code %d)\n", rc); DEBUGF( "fat_mount() - Couldn't read FSInfo (error code %d)\n", rc);
return rc * 10 - 4; return rc * 10 - 4;
} }
fat_bpb->fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT); fat_bpb->fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT);
fat_bpb->fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); fat_bpb->fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE);
} }
fat_release_sector_buffer();
return 0; return 0;
} }
void* fat_get_sector_buffer()
{
mutex_lock(&tempbuf_mutex);
if (tempbuf_locked)
panicf("FAT: Tried to lock temporary sector buffer twice!");
tempbuf_locked = true;
return fat_tempbuf;
}
void fat_release_sector_buffer()
{
tempbuf_locked = false;
mutex_unlock(&tempbuf_mutex);
}
#ifdef MAX_LOG_SECTOR_SIZE #ifdef MAX_LOG_SECTOR_SIZE
int fat_get_bytes_per_sector(IF_MV_NONVOID(int volume)) int fat_get_bytes_per_sector(IF_MV_NONVOID(int volume))
{ {
@ -961,7 +993,6 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
#ifndef HAVE_MULTIVOLUME #ifndef HAVE_MULTIVOLUME
struct bpb* fat_bpb = &fat_bpbs[0]; struct bpb* fat_bpb = &fat_bpbs[0];
#endif #endif
unsigned char fsinfo[SECTOR_SIZE];
unsigned long* intptr; unsigned long* intptr;
int rc; int rc;
@ -970,12 +1001,14 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
return 0; /* FAT16 has no FsInfo */ return 0; /* FAT16 has no FsInfo */
#endif /* #ifdef HAVE_FAT16SUPPORT */ #endif /* #ifdef HAVE_FAT16SUPPORT */
unsigned char* fsinfo = fat_get_sector_buffer();
/* update fsinfo */ /* update fsinfo */
rc = storage_read_sectors(IF_MD2(fat_bpb->drive,) rc = storage_read_sectors(IF_MD2(fat_bpb->drive,)
fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo); fat_bpb->startsector + fat_bpb->bpb_fsinfo, 1,fsinfo);
if (rc < 0) if (rc < 0)
{ {
DEBUGF( "flush_fat() - Couldn't read FSInfo (error code %d)\n", rc); fat_release_sector_buffer();
DEBUGF( "update_fsinfo() - Couldn't read FSInfo (error code %d)", rc);
return rc * 10 - 1; return rc * 10 - 1;
} }
intptr = (long*)&(fsinfo[FSINFO_FREECOUNT]); intptr = (long*)&(fsinfo[FSINFO_FREECOUNT]);
@ -986,9 +1019,10 @@ static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb))
rc = storage_write_sectors(IF_MD2(fat_bpb->drive,) rc = storage_write_sectors(IF_MD2(fat_bpb->drive,)
fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo); fat_bpb->startsector + fat_bpb->bpb_fsinfo,1,fsinfo);
fat_release_sector_buffer();
if (rc < 0) if (rc < 0)
{ {
DEBUGF( "flush_fat() - Couldn't write FSInfo (error code %d)\n", rc); DEBUGF( "update_fsinfo() - Couldn't write FSInfo (error code %d)", rc);
return rc * 10 - 2; return rc * 10 - 2;
} }
@ -1128,8 +1162,7 @@ static int write_long_name(struct fat_file* file,
unsigned int numentries, unsigned int numentries,
const unsigned char* name, const unsigned char* name,
const unsigned char* shortname, const unsigned char* shortname,
bool is_directory, bool is_directory)
unsigned char *sector_buffer)
{ {
unsigned char* entry; unsigned char* entry;
unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR; unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR;
@ -1147,9 +1180,13 @@ static int write_long_name(struct fat_file* file,
if (rc<0) if (rc<0)
return rc * 10 - 1; return rc * 10 - 1;
rc = fat_readwrite(file, 1, sector_buffer, false); unsigned char* buf = fat_get_sector_buffer();
rc = fat_readwrite(file, 1, buf, false);
if (rc<1) if (rc<1)
{
fat_release_sector_buffer();
return rc * 10 - 2; return rc * 10 - 2;
}
/* calculate shortname checksum */ /* calculate shortname checksum */
for (i=11; i>0; i--) for (i=11; i>0; i--)
@ -1172,34 +1209,44 @@ static int write_long_name(struct fat_file* file,
/* update current sector */ /* update current sector */
rc = fat_seek(file, sector); rc = fat_seek(file, sector);
if (rc<0) if (rc<0)
{
fat_release_sector_buffer();
return rc * 10 - 3; return rc * 10 - 3;
}
rc = fat_readwrite(file, 1, sector_buffer, true); rc = fat_readwrite(file, 1, buf, true);
if (rc<1) if (rc<1)
{
fat_release_sector_buffer();
return rc * 10 - 4; return rc * 10 - 4;
}
/* read next sector */ /* read next sector */
rc = fat_readwrite(file, 1, sector_buffer, false); rc = fat_readwrite(file, 1, buf, false);
if (rc<0) { if (rc<0) {
fat_release_sector_buffer();
LDEBUGF("Failed writing new sector: %d\n",rc); LDEBUGF("Failed writing new sector: %d\n",rc);
return rc * 10 - 5; return rc * 10 - 5;
} }
if (rc==0) if (rc==0)
/* end of dir */ /* end of dir */
memset(sector_buffer, 0, SECTOR_SIZE); memset(buf, 0, SECTOR_SIZE);
sector++; sector++;
idx = 0; idx = 0;
} }
entry = sector_buffer + idx * DIR_ENTRY_SIZE; entry = buf + idx * DIR_ENTRY_SIZE;
/* verify this entry is free */ /* verify this entry is free */
if (entry[0] && entry[0] != 0xe5 ) if (entry[0] && entry[0] != 0xe5 )
{
fat_release_sector_buffer();
panicf("Dir entry %d in sector %x is not free! " panicf("Dir entry %d in sector %x is not free! "
"%02x %02x %02x %02x", "%02x %02x %02x %02x",
idx, sector, idx, sector,
entry[0], entry[1], entry[2], entry[3]); entry[0], entry[1], entry[2], entry[3]);
}
memset(entry, 0, DIR_ENTRY_SIZE); memset(entry, 0, DIR_ENTRY_SIZE);
if ( i+1 < numentries ) { if ( i+1 < numentries ) {
@ -1259,9 +1306,13 @@ static int write_long_name(struct fat_file* file,
/* update last sector */ /* update last sector */
rc = fat_seek(file, sector); rc = fat_seek(file, sector);
if (rc<0) if (rc<0)
{
fat_release_sector_buffer();
return rc * 10 - 6; return rc * 10 - 6;
}
rc = fat_readwrite(file, 1, sector_buffer, true); rc = fat_readwrite(file, 1, buf, true);
fat_release_sector_buffer();
if (rc<1) if (rc<1)
return rc * 10 - 7; return rc * 10 - 7;
@ -1301,7 +1352,6 @@ static int add_dir_entry(struct fat_dir* dir,
#else #else
struct bpb* fat_bpb = &fat_bpbs[0]; struct bpb* fat_bpb = &fat_bpbs[0];
#endif #endif
unsigned char buf[SECTOR_SIZE];
unsigned char shortname[12]; unsigned char shortname[12];
int rc; int rc;
unsigned int sector; unsigned int sector;
@ -1342,12 +1392,16 @@ static int add_dir_entry(struct fat_dir* dir,
/ NAME_BYTES_PER_ENTRY + 1; / NAME_BYTES_PER_ENTRY + 1;
} }
unsigned char* buf = fat_get_sector_buffer();
restart: restart:
firstentry = -1; firstentry = -1;
rc = fat_seek(&dir->file, 0); rc = fat_seek(&dir->file, 0);
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 2; return rc * 10 - 2;
}
/* step 1: search for free entries and check for duplicate shortname */ /* step 1: search for free entries and check for duplicate shortname */
for (sector = 0; !done; sector++) for (sector = 0; !done; sector++)
@ -1356,6 +1410,7 @@ static int add_dir_entry(struct fat_dir* dir,
rc = fat_readwrite(&dir->file, 1, buf, false); rc = fat_readwrite(&dir->file, 1, buf, false);
if (rc < 0) { if (rc < 0) {
fat_release_sector_buffer();
DEBUGF( "add_dir_entry() - Couldn't read dir" DEBUGF( "add_dir_entry() - Couldn't read dir"
" (error code %d)\n", rc); " (error code %d)\n", rc);
return rc * 10 - 3; return rc * 10 - 3;
@ -1412,25 +1467,35 @@ static int add_dir_entry(struct fat_dir* dir,
LDEBUGF("Adding new sector(s) to dir\n"); LDEBUGF("Adding new sector(s) to dir\n");
rc = fat_seek(&dir->file, sector); rc = fat_seek(&dir->file, sector);
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 4; return rc * 10 - 4;
memset(buf, 0, sizeof buf); }
memset(buf, 0, SECTOR_SIZE);
/* we must clear whole clusters */ /* we must clear whole clusters */
for (; (entries_found < entries_needed) || for (; (entries_found < entries_needed) ||
(dir->file.sectornum < (int)fat_bpb->bpb_secperclus); sector++) (dir->file.sectornum < (int)fat_bpb->bpb_secperclus); sector++)
{ {
if (sector >= (65536/DIR_ENTRIES_PER_SECTOR)) if (sector >= (65536/DIR_ENTRIES_PER_SECTOR))
{
fat_release_sector_buffer();
return -5; /* dir too large -- FAT specification */ return -5; /* dir too large -- FAT specification */
}
rc = fat_readwrite(&dir->file, 1, buf, true); rc = fat_readwrite(&dir->file, 1, buf, true);
if (rc < 1) /* No more room or something went wrong */ if (rc < 1) /* No more room or something went wrong */
{
fat_release_sector_buffer();
return rc * 10 - 6; return rc * 10 - 6;
}
entries_found += DIR_ENTRIES_PER_SECTOR; entries_found += DIR_ENTRIES_PER_SECTOR;
} }
firstentry = sector * DIR_ENTRIES_PER_SECTOR - entries_found; firstentry = sector * DIR_ENTRIES_PER_SECTOR - entries_found;
} }
fat_release_sector_buffer();
/* step 3: add entry */ /* step 3: add entry */
sector = firstentry / DIR_ENTRIES_PER_SECTOR; sector = firstentry / DIR_ENTRIES_PER_SECTOR;
@ -1439,7 +1504,7 @@ static int add_dir_entry(struct fat_dir* dir,
rc = write_long_name(&dir->file, firstentry, rc = write_long_name(&dir->file, firstentry,
entries_needed, name, entries_needed, name,
shortname, is_directory, buf); shortname, is_directory);
if (rc < 0) if (rc < 0)
return rc * 10 - 7; return rc * 10 - 7;
@ -1559,10 +1624,7 @@ static void randomize_dos_name(unsigned char *name)
static int update_short_entry( struct fat_file* file, long size, int attr ) static int update_short_entry( struct fat_file* file, long size, int attr )
{ {
unsigned char buf[SECTOR_SIZE];
int sector = file->direntry / DIR_ENTRIES_PER_SECTOR; int sector = file->direntry / DIR_ENTRIES_PER_SECTOR;
unsigned char* entry =
buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);
unsigned long* sizeptr; unsigned long* sizeptr;
unsigned short* clusptr; unsigned short* clusptr;
struct fat_file dir; struct fat_file dir;
@ -1580,12 +1642,21 @@ static int update_short_entry( struct fat_file* file, long size, int attr )
if (rc<0) if (rc<0)
return rc * 10 - 2; return rc * 10 - 2;
unsigned char* buf = fat_get_sector_buffer();
unsigned char* entry =
buf + DIR_ENTRY_SIZE * (file->direntry % DIR_ENTRIES_PER_SECTOR);
rc = fat_readwrite(&dir, 1, buf, false); rc = fat_readwrite(&dir, 1, buf, false);
if (rc < 1) if (rc < 1)
{
fat_release_sector_buffer();
return rc * 10 - 3; return rc * 10 - 3;
}
if (!entry[0] || entry[0] == 0xe5) if (!entry[0] || entry[0] == 0xe5)
{
fat_release_sector_buffer();
panicf("Updating size on empty dir entry %d\n", file->direntry); panicf("Updating size on empty dir entry %d\n", file->direntry);
}
entry[FATDIR_ATTR] = attr & 0xFF; entry[FATDIR_ATTR] = attr & 0xFF;
@ -1615,9 +1686,13 @@ static int update_short_entry( struct fat_file* file, long size, int attr )
rc = fat_seek( &dir, sector ); rc = fat_seek( &dir, sector );
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 4; return rc * 10 - 4;
}
rc = fat_readwrite(&dir, 1, buf, true); rc = fat_readwrite(&dir, 1, buf, true);
fat_release_sector_buffer();
if (rc < 1) if (rc < 1)
return rc * 10 - 5; return rc * 10 - 5;
@ -1720,18 +1795,22 @@ int fat_create_file(const char* name,
/* noinline because this is only split out of fat_create_dir to make sure /* noinline because this is only split out of fat_create_dir to make sure
* the sector buffer doesn't remain on the stack, to avoid nasty stack * the sector buffer doesn't remain on the stack, to avoid nasty stack
* overflows later on (when flush_fat() is called */ * overflows later on (when flush_fat() is called) */
static __attribute__((noinline)) int fat_clear_cluster(int sector, static __attribute__((noinline)) int fat_clear_cluster(int sector,
struct bpb *fat_bpb) struct bpb *fat_bpb)
{ {
unsigned char buf[SECTOR_SIZE]; unsigned char* buf = fat_get_sector_buffer();
int i,rc; int i,rc;
memset(buf, 0, sizeof buf); memset(buf, 0, SECTOR_SIZE);
for(i = 0;i < (int)fat_bpb->bpb_secperclus;i++) { for(i = 0;i < (int)fat_bpb->bpb_secperclus;i++) {
rc = transfer(IF_MV2(fat_bpb,) sector + i, 1, buf, true ); rc = transfer(IF_MV2(fat_bpb,) sector + i, 1, buf, true );
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 2; return rc * 10 - 2;
} }
}
fat_release_sector_buffer();
return 0; return 0;
} }
@ -1878,7 +1957,6 @@ int fat_closewrite(struct fat_file *file, long size, int attr)
static int free_direntries(struct fat_file* file) static int free_direntries(struct fat_file* file)
{ {
unsigned char buf[SECTOR_SIZE];
struct fat_file dir; struct fat_file dir;
int numentries = file->direntries; int numentries = file->direntries;
unsigned int entry = file->direntry - numentries + 1; unsigned int entry = file->direntry - numentries + 1;
@ -1895,9 +1973,13 @@ static int free_direntries(struct fat_file* file)
if (rc < 0) if (rc < 0)
return rc * 10 - 2; return rc * 10 - 2;
unsigned char* buf = fat_get_sector_buffer();
rc = fat_readwrite(&dir, 1, buf, false); rc = fat_readwrite(&dir, 1, buf, false);
if (rc < 1) if (rc < 1)
{
fat_release_sector_buffer();
return rc * 10 - 3; return rc * 10 - 3;
}
for (i=0; i < numentries; i++) { for (i=0; i < numentries; i++) {
LDEBUGF("Clearing dir entry %d (%d/%d)\n", LDEBUGF("Clearing dir entry %d (%d/%d)\n",
@ -1909,18 +1991,27 @@ static int free_direntries(struct fat_file* file)
/* flush this sector */ /* flush this sector */
rc = fat_seek(&dir, sector); rc = fat_seek(&dir, sector);
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 4; return rc * 10 - 4;
}
rc = fat_readwrite(&dir, 1, buf, true); rc = fat_readwrite(&dir, 1, buf, true);
if (rc < 1) if (rc < 1)
{
fat_release_sector_buffer();
return rc * 10 - 5; return rc * 10 - 5;
}
if ( i+1 < numentries ) { if ( i+1 < numentries ) {
/* read next sector */ /* read next sector */
rc = fat_readwrite(&dir, 1, buf, false); rc = fat_readwrite(&dir, 1, buf, false);
if (rc < 1) if (rc < 1)
{
fat_release_sector_buffer();
return rc * 10 - 6; return rc * 10 - 6;
} }
}
sector++; sector++;
} }
} }
@ -1929,12 +2020,19 @@ static int free_direntries(struct fat_file* file)
/* flush this sector */ /* flush this sector */
rc = fat_seek(&dir, sector); rc = fat_seek(&dir, sector);
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 7; return rc * 10 - 7;
}
rc = fat_readwrite(&dir, 1, buf, true); rc = fat_readwrite(&dir, 1, buf, true);
if (rc < 1) if (rc < 1)
{
fat_release_sector_buffer();
return rc * 10 - 8; return rc * 10 - 8;
} }
}
fat_release_sector_buffer();
return 0; return 0;
} }
@ -2021,7 +2119,6 @@ int fat_rename(struct fat_file* file,
/* if renaming a directory, update the .. entry to make sure /* if renaming a directory, update the .. entry to make sure
it points to its parent directory (we don't check if it was a move) */ it points to its parent directory (we don't check if it was a move) */
if(FAT_ATTR_DIRECTORY == attr) { if(FAT_ATTR_DIRECTORY == attr) {
unsigned char buf[SECTOR_SIZE];
/* open the dir that was renamed, we re-use the olddir_file struct */ /* open the dir that was renamed, we re-use the olddir_file struct */
rc = fat_open(IF_MV2(file->volume,) newfile.firstcluster, &olddir_file, NULL); rc = fat_open(IF_MV2(file->volume,) newfile.firstcluster, &olddir_file, NULL);
if (rc < 0) if (rc < 0)
@ -2032,9 +2129,13 @@ int fat_rename(struct fat_file* file,
if (rc < 0) if (rc < 0)
return rc * 10 - 7; return rc * 10 - 7;
unsigned char* buf = fat_get_sector_buffer();
rc = fat_readwrite(&olddir_file, 1, buf, false); rc = fat_readwrite(&olddir_file, 1, buf, false);
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 8; return rc * 10 - 8;
}
/* parent cluster is 0 if parent dir is the root - FAT spec (p.29) */ /* parent cluster is 0 if parent dir is the root - FAT spec (p.29) */
if(dir->file.firstcluster == fat_bpb->bpb_rootclus) if(dir->file.firstcluster == fat_bpb->bpb_rootclus)
@ -2045,6 +2146,7 @@ int fat_rename(struct fat_file* file,
entry = buf + DIR_ENTRY_SIZE; entry = buf + DIR_ENTRY_SIZE;
if(strncmp(".. ", entry, 11)) if(strncmp(".. ", entry, 11))
{ {
fat_release_sector_buffer();
/* .. entry must be second entry according to FAT spec (p.29) */ /* .. entry must be second entry according to FAT spec (p.29) */
DEBUGF("Second dir entry is not double-dot!\n"); DEBUGF("Second dir entry is not double-dot!\n");
return rc * 10 - 9; return rc * 10 - 9;
@ -2058,9 +2160,13 @@ int fat_rename(struct fat_file* file,
/* write back this sector */ /* write back this sector */
rc = fat_seek(&olddir_file, 0); rc = fat_seek(&olddir_file, 0);
if (rc < 0) if (rc < 0)
{
fat_release_sector_buffer();
return rc * 10 - 7; return rc * 10 - 7;
}
rc = fat_readwrite(&olddir_file, 1, buf, true); rc = fat_readwrite(&olddir_file, 1, buf, true);
fat_release_sector_buffer();
if (rc < 1) if (rc < 1)
return rc * 10 - 8; return rc * 10 - 8;
} }

View file

@ -134,5 +134,7 @@ extern int fat_opendir(IF_MV2(int volume,)
extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry); extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry);
extern unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); /* public for debug info screen */ extern unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); /* public for debug info screen */
extern bool fat_ismounted(int volume); extern bool fat_ismounted(int volume);
extern void* fat_get_sector_buffer(void);
extern void fat_release_sector_buffer(void);
#endif #endif

View file

@ -77,7 +77,7 @@ static int usb_mmc_countdown = 0;
/* Make sure there's enough stack space for screendump */ /* Make sure there's enough stack space for screendump */
#ifdef USB_FULL_INIT #ifdef USB_FULL_INIT
static long usb_stack[(DEFAULT_STACK_SIZE + SECTOR_SIZE + DUMP_BMP_LINESIZE)/sizeof(long)]; static long usb_stack[(DEFAULT_STACK_SIZE + DUMP_BMP_LINESIZE)/sizeof(long)];
static const char usb_thread_name[] = "usb"; static const char usb_thread_name[] = "usb";
static unsigned int usb_thread_entry = 0; static unsigned int usb_thread_entry = 0;
static bool usb_monitor_enabled = false; static bool usb_monitor_enabled = false;

View file

@ -27,6 +27,7 @@
#include "logf.h" #include "logf.h"
#include "storage.h" #include "storage.h"
#include "disk.h" #include "disk.h"
#include "fat.h"
/* Needed to get at the audio buffer */ /* Needed to get at the audio buffer */
#include "audio.h" #include "audio.h"
#include "usb_storage.h" #include "usb_storage.h"
@ -358,8 +359,10 @@ static bool check_disk_present(IF_MD_NONVOID(int volume))
#ifdef USB_USE_RAMDISK #ifdef USB_USE_RAMDISK
return true; return true;
#else #else
unsigned char sector[SECTOR_SIZE]; unsigned char* sector = fat_get_sector_buffer();
return storage_read_sectors(IF_MD2(volume,)0,1,sector) == 0; bool success = storage_read_sectors(IF_MD2(volume,)0,1,sector) == 0;
fat_release_sector_buffer();
return success;
#endif #endif
} }