mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
fs/fat: correct FAT16/12 file finding in root dir
When write a file into FAT file system, it will search a match file in root dir. So the find_directory_entry() will get the first cluster of root dir content and search the directory item one by one. If the file is not found, we will call get_fatent_value() to get next cluster of root dir via lookup the FAT table and continue the search. The issue is in FAT16/12 system, we cannot get root dir's next clust from FAT table. The FAT table only be use to find the clust of data aera in FAT16/12. In FAT16/12 if the clust is in root dir, the clust number is a negative number or 0, 1. Since root dir is located in front of the data area. Data area start clust #2. So the root dir clust number should < 2. This patch will check above situation before call get_fatenv_value(). If curclust is < 2, include minus number, we just increase one on the curclust since root dir is in continous cluster. The patch also add a sanity check for entry in get_fatenv_value(). Signed-off-by: Josh Wu <josh.wu@atmel.com>
This commit is contained in:
parent
2e98f70882
commit
dd6d7967df
1 changed files with 27 additions and 0 deletions
|
@ -139,6 +139,11 @@ static __u32 get_fatent_value(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;
|
||||
|
@ -881,6 +886,28 @@ static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
|
|||
return dentptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* In FAT16/12, the root dir is locate before data area, shows
|
||||
* in following:
|
||||
* -------------------------------------------------------------
|
||||
* | Boot | FAT1 & 2 | Root dir | Data (start from cluster #2) |
|
||||
* -------------------------------------------------------------
|
||||
*
|
||||
* As a result if curclust is in Root dir, it is a negative
|
||||
* number or 0, 1.
|
||||
*
|
||||
*/
|
||||
if (mydata->fatsize != 32 && (int)curclust <= 1) {
|
||||
/* Current clust is in root dir, set to next clust */
|
||||
curclust++;
|
||||
if ((int)curclust <= 1)
|
||||
continue; /* continue to find */
|
||||
|
||||
/* Reach the end of root dir */
|
||||
empty_dentptr = dentptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curclust = get_fatent_value(mydata, dir_curclust);
|
||||
if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
|
||||
empty_dentptr = dentptr;
|
||||
|
|
Loading…
Reference in a new issue