fs/fat: merge readwrite get_fatent_value() with readonly get_fatent()
get_fatent_value(...) flushes changed FAT entries to disk when fetching the next FAT blocks, in every other aspect it is identical to get_fatent(...). Provide a stub implementation for flush_dirty_fat_buffer if CONFIG_FAT_WRITE is not set. Calling flush_dirty_fat_buffer during read only operation is fine as it checks if any buffers needs flushing. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
This commit is contained in:
parent
6c1a808052
commit
b8948d2aef
25
fs/fat/fat.c
25
fs/fat/fat.c
@ -162,6 +162,16 @@ static void get_name(dir_entry *dirent, char *s_name)
|
||||
downcase(s_name);
|
||||
}
|
||||
|
||||
static int flush_dirty_fat_buffer(fsdata *mydata);
|
||||
#if !defined(CONFIG_FAT_WRITE)
|
||||
/* Stub for read only operation */
|
||||
int flush_dirty_fat_buffer(fsdata *mydata)
|
||||
{
|
||||
(void)(mydata);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the entry at index 'entry' in a FAT (12/16/32) table.
|
||||
* On failure 0x00 is returned.
|
||||
@ -173,6 +183,11 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
|
||||
__u32 ret = 0x00;
|
||||
__u16 val1, val2;
|
||||
|
||||
if (CHECK_CLUST(entry, mydata->fatsize)) {
|
||||
printf("Error: Invalid FAT entry: 0x%08x\n", entry);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (mydata->fatsize) {
|
||||
case 32:
|
||||
bufnum = entry / FAT32BUFSIZE;
|
||||
@ -192,7 +207,7 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug("FAT%d: entry: 0x%04x = %d, offset: 0x%04x = %d\n",
|
||||
debug("FAT%d: entry: 0x%08x = %d, offset: 0x%04x = %d\n",
|
||||
mydata->fatsize, entry, entry, offset, offset);
|
||||
|
||||
/* Read a new block of FAT entries into the cache. */
|
||||
@ -208,6 +223,10 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
|
||||
|
||||
startblock += mydata->fat_sect; /* Offset from start of disk */
|
||||
|
||||
/* Write back the fatbuf to the disk */
|
||||
if (flush_dirty_fat_buffer(mydata) < 0)
|
||||
return -1;
|
||||
|
||||
if (disk_read(startblock, getsize, bufptr) < 0) {
|
||||
debug("Error reading FAT blocks\n");
|
||||
return ret;
|
||||
@ -254,8 +273,8 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
|
||||
}
|
||||
break;
|
||||
}
|
||||
debug("FAT%d: ret: %08x, offset: %04x\n",
|
||||
mydata->fatsize, ret, offset);
|
||||
debug("FAT%d: ret: 0x%08x, entry: 0x%08x, offset: 0x%04x\n",
|
||||
mydata->fatsize, ret, entry, offset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -142,114 +142,6 @@ static int flush_dirty_fat_buffer(fsdata *mydata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the entry at index 'entry' in a FAT (12/16/32) table.
|
||||
* On failure 0x00 is returned.
|
||||
* When bufnum is changed, write back the previous fatbuf to the disk.
|
||||
*/
|
||||
static __u32 get_fatent_value(fsdata *mydata, __u32 entry)
|
||||
{
|
||||
__u32 bufnum;
|
||||
__u32 off16, offset;
|
||||
__u32 ret = 0x00;
|
||||
__u16 val1, val2;
|
||||
|
||||
if (CHECK_CLUST(entry, mydata->fatsize)) {
|
||||
printf("Error: Invalid FAT entry: 0x%08x\n", entry);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (mydata->fatsize) {
|
||||
case 32:
|
||||
bufnum = entry / FAT32BUFSIZE;
|
||||
offset = entry - bufnum * FAT32BUFSIZE;
|
||||
break;
|
||||
case 16:
|
||||
bufnum = entry / FAT16BUFSIZE;
|
||||
offset = entry - bufnum * FAT16BUFSIZE;
|
||||
break;
|
||||
case 12:
|
||||
bufnum = entry / FAT12BUFSIZE;
|
||||
offset = entry - bufnum * FAT12BUFSIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unsupported FAT size */
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug("FAT%d: entry: 0x%04x = %d, offset: 0x%04x = %d\n",
|
||||
mydata->fatsize, entry, entry, offset, offset);
|
||||
|
||||
/* Read a new block of FAT entries into the cache. */
|
||||
if (bufnum != mydata->fatbufnum) {
|
||||
int getsize = FATBUFBLOCKS;
|
||||
__u8 *bufptr = mydata->fatbuf;
|
||||
__u32 fatlength = mydata->fatlength;
|
||||
__u32 startblock = bufnum * FATBUFBLOCKS;
|
||||
|
||||
/* Cap length if fatlength is not a multiple of FATBUFBLOCKS */
|
||||
if (startblock + getsize > fatlength)
|
||||
getsize = fatlength - startblock;
|
||||
|
||||
startblock += mydata->fat_sect; /* Offset from start of disk */
|
||||
|
||||
/* Write back the fatbuf to the disk */
|
||||
if (flush_dirty_fat_buffer(mydata) < 0)
|
||||
return -1;
|
||||
|
||||
if (disk_read(startblock, getsize, bufptr) < 0) {
|
||||
debug("Error reading FAT blocks\n");
|
||||
return ret;
|
||||
}
|
||||
mydata->fatbufnum = bufnum;
|
||||
}
|
||||
|
||||
/* Get the actual entry from the table */
|
||||
switch (mydata->fatsize) {
|
||||
case 32:
|
||||
ret = FAT2CPU32(((__u32 *) mydata->fatbuf)[offset]);
|
||||
break;
|
||||
case 16:
|
||||
ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[offset]);
|
||||
break;
|
||||
case 12:
|
||||
off16 = (offset * 3) / 4;
|
||||
|
||||
switch (offset & 0x3) {
|
||||
case 0:
|
||||
ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[off16]);
|
||||
ret &= 0xfff;
|
||||
break;
|
||||
case 1:
|
||||
val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
|
||||
val1 &= 0xf000;
|
||||
val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
|
||||
val2 &= 0x00ff;
|
||||
ret = (val2 << 4) | (val1 >> 12);
|
||||
break;
|
||||
case 2:
|
||||
val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
|
||||
val1 &= 0xff00;
|
||||
val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
|
||||
val2 &= 0x000f;
|
||||
ret = (val2 << 8) | (val1 >> 8);
|
||||
break;
|
||||
case 3:
|
||||
ret = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
|
||||
ret = (ret & 0xfff0) >> 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
debug("FAT%d: ret: %08x, entry: %08x, offset: %04x\n",
|
||||
mydata->fatsize, ret, entry, offset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the file name information from 'name' into 'slotptr',
|
||||
*/
|
||||
@ -407,7 +299,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster,
|
||||
if ((__u8 *)slotptr >= buflimit) {
|
||||
if (curclust == 0)
|
||||
return -1;
|
||||
curclust = get_fatent_value(mydata, dir_curclust);
|
||||
curclust = get_fatent(mydata, dir_curclust);
|
||||
if (CHECK_CLUST(curclust, mydata->fatsize)) {
|
||||
debug("curclust: 0x%x\n", curclust);
|
||||
printf("Invalid FAT entry\n");
|
||||
@ -583,7 +475,7 @@ static __u32 determine_fatent(fsdata *mydata, __u32 entry)
|
||||
__u32 next_fat, next_entry = entry + 1;
|
||||
|
||||
while (1) {
|
||||
next_fat = get_fatent_value(mydata, next_entry);
|
||||
next_fat = get_fatent(mydata, next_entry);
|
||||
if (next_fat == 0) {
|
||||
/* found free entry, link to entry */
|
||||
set_fatent_value(mydata, entry, next_entry);
|
||||
@ -669,7 +561,7 @@ static int find_empty_cluster(fsdata *mydata)
|
||||
__u32 fat_val, entry = 3;
|
||||
|
||||
while (1) {
|
||||
fat_val = get_fatent_value(mydata, entry);
|
||||
fat_val = get_fatent(mydata, entry);
|
||||
if (fat_val == 0)
|
||||
break;
|
||||
entry++;
|
||||
@ -719,7 +611,7 @@ static int clear_fatent(fsdata *mydata, __u32 entry)
|
||||
__u32 fat_val;
|
||||
|
||||
while (!CHECK_CLUST(entry, mydata->fatsize)) {
|
||||
fat_val = get_fatent_value(mydata, entry);
|
||||
fat_val = get_fatent(mydata, entry);
|
||||
if (fat_val != 0)
|
||||
set_fatent_value(mydata, entry, 0);
|
||||
else
|
||||
@ -996,7 +888,7 @@ static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curclust = get_fatent_value(mydata, dir_curclust);
|
||||
curclust = get_fatent(mydata, dir_curclust);
|
||||
if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
|
||||
empty_dentptr = dentptr;
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user