提交 eb9b7c3f 编写于 作者: F Far

fix: statfs can't get f_bfree and f_bavail of a FAT12/FAT16 partition

FAT12/FAT16 partition has no FSINFO sector storing the free cluster number,
so scanning the FAT is necessary to get the free clusters nums.

Close #I3Q0VS
上级 c9c6b40b
...@@ -4290,35 +4290,17 @@ FRESULT f_stat ( ...@@ -4290,35 +4290,17 @@ FRESULT f_stat (
} }
FRESULT fat_count_free_entries(
#if !FF_FS_READONLY DWORD *nclst, /* Pointer to a variable to return number of free clusters */
/*-----------------------------------------------------------------------*/ FATFS *fs /* Pointer to corresponding filesystem object */
/* Get Number of Free Clusters */
/*-----------------------------------------------------------------------*/
FRESULT f_getfree (
const TCHAR* path, /* Logical drive number */
DWORD* nclst, /* Pointer to a variable to return number of free clusters */
FATFS** fatfs /* Pointer to return pointer to corresponding filesystem object */
) )
{ {
FRESULT res;
FATFS *fs;
DWORD nfree, clst, stat; DWORD nfree, clst, stat;
QWORD sect; QWORD sect;
UINT i; UINT i;
FFOBJID obj; FFOBJID obj;
FRESULT res = FR_OK;
/* Get logical drive */
res = find_volume(&path, &fs, 0);
if (res == FR_OK) {
*fatfs = fs; /* Return ptr to the fs object */
/* If free_clst is valid, return it without full FAT scan */
if (fs->free_clst <= fs->n_fatent - 2) {
*nclst = fs->free_clst;
} else {
/* Scan FAT to obtain number of free clusters */
nfree = 0; nfree = 0;
if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */
clst = 2; obj.fs = fs; clst = 2; obj.fs = fs;
...@@ -4351,6 +4333,33 @@ FRESULT f_getfree ( ...@@ -4351,6 +4333,33 @@ FRESULT f_getfree (
*nclst = nfree; /* Return the free clusters */ *nclst = nfree; /* Return the free clusters */
fs->free_clst = nfree; /* Now free_clst is valid */ fs->free_clst = nfree; /* Now free_clst is valid */
fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */
return res;
}
#if !FF_FS_READONLY
/*-----------------------------------------------------------------------*/
/* Get Number of Free Clusters */
/*-----------------------------------------------------------------------*/
FRESULT f_getfree (
const TCHAR* path, /* Logical drive number */
DWORD* nclst, /* Pointer to a variable to return number of free clusters */
FATFS** fatfs /* Pointer to return pointer to corresponding filesystem object */
)
{
FRESULT res;
FATFS *fs;
/* Get logical drive */
res = find_volume(&path, &fs, 0);
if (res == FR_OK) {
*fatfs = fs; /* Return ptr to the fs object */
/* If free_clst is valid, return it without full FAT scan */
if (fs->free_clst <= fs->n_fatent - 2) {
*nclst = fs->free_clst;
} else {
/* Scan FAT to obtain number of free clusters */
res = fat_count_free_entries(nclst, fs);
} }
} }
......
...@@ -450,7 +450,8 @@ FRESULT f_getclustinfo (FIL* fp, DWORD* fclust, DWORD* fcount); /* get the clust ...@@ -450,7 +450,8 @@ FRESULT f_getclustinfo (FIL* fp, DWORD* fclust, DWORD* fcount); /* get the clust
FRESULT f_checkopenlock(int index); FRESULT f_checkopenlock(int index);
FRESULT sync_fs (FATFS* fs); FRESULT sync_fs (FATFS* fs);
FRESULT sync_window(FATFS *fs); FRESULT sync_window(FATFS *fs);
FRESULT move_window ( FATFS* fs, QWORD sector); FRESULT move_window (FATFS* fs, QWORD sector);
FRESULT fat_count_free_entries(DWORD *nclst, FATFS *fs);
void get_fileinfo (DIR* dp, FILINFO* fno); void get_fileinfo (DIR* dp, FILINFO* fno);
DWORD get_fat (FFOBJID *obj, DWORD clst); DWORD get_fat (FFOBJID *obj, DWORD clst);
FRESULT put_fat(FATFS *fs, DWORD clst, DWORD val); FRESULT put_fat(FATFS *fs, DWORD clst, DWORD val);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册