diff options
Diffstat (limited to 'lib/fatfs/src/ff.c')
| -rw-r--r-- | lib/fatfs/src/ff.c | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/lib/fatfs/src/ff.c b/lib/fatfs/src/ff.c index 52adc2ab..3c3f1ace 100644 --- a/lib/fatfs/src/ff.c +++ b/lib/fatfs/src/ff.c @@ -34,7 +34,6 @@ #error Wrong include file (ff.h). #endif - /* Limits and boundaries */ #define MAX_DIR 0x200000 /* Max size of FAT directory */ #define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ @@ -43,6 +42,10 @@ #define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ #define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ +#define MIN_FAT12_SEC_VOL 4 /* Min size of the FAT sector volume + 1 FAT, 1 root dir, 1 reserved, 1 data sector */ +#define MIN_FAT12_DATA_SEC 1 /* Min FAT data sectors */ + /* Character code support macros */ #define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') @@ -1118,7 +1121,7 @@ static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ if (res == FR_OK) { if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ /* Create FSInfo structure */ - memset(fs->win, 0, sizeof fs->win); + memset(fs->win, 0, SS(fs)); st_word(fs->win + BS_55AA, 0xAA55); /* Boot signature */ st_dword(fs->win + FSI_LeadSig, 0x41615252); /* Leading signature */ st_dword(fs->win + FSI_StrucSig, 0x61417272); /* Structure signature */ @@ -1670,7 +1673,7 @@ static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ sect = clst2sect(fs, clst); /* Top of the cluster */ fs->winsect = sect; /* Set window to top of the cluster */ - memset(fs->win, 0, sizeof fs->win); /* Clear window buffer */ + memset(fs->win, 0, SS(fs)); /* Clear window buffer */ #if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ /* Allocate a temporary buffer */ for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; @@ -3318,7 +3321,7 @@ static UINT check_fs ( /* 0:FAT/FAT32 VBR, 1:exFAT VBR, 2:Not FAT and valid BS, && ld_word(fs->win + BPB_RsvdSecCnt) != 0 /* Properness of reserved sectors (MNBZ) */ && (UINT)fs->win[BPB_NumFATs] - 1 <= 1 /* Properness of FATs (1 or 2) */ && ld_word(fs->win + BPB_RootEntCnt) != 0 /* Properness of root dir entries (MNBZ) */ - && (ld_word(fs->win + BPB_TotSec16) >= 128 || ld_dword(fs->win + BPB_TotSec32) >= 0x10000) /* Properness of volume sectors (>=128) */ + && (ld_word(fs->win + BPB_TotSec16) >= MIN_FAT12_SEC_VOL || ld_dword(fs->win + BPB_TotSec32) >= 0x10000) /* Properness of volume sectors (>=MIN_FAT12_SEC_VOL) */ && ld_word(fs->win + BPB_FATSz16) != 0) { /* Properness of FAT size (MNBZ) */ return 0; /* It can be presumed an FAT VBR */ } @@ -3438,6 +3441,10 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR; if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; #endif +#if FF_USE_DYN_BUFFER + fs->win = ff_memalloc(SS(fs)); /* Allocate memory for sector buffer */ + if (!fs->win) return FR_NOT_ENOUGH_CORE; +#endif /* Find an FAT volume on the hosting drive */ fmt = find_volume(fs, LD2PT(vol)); @@ -3681,6 +3688,10 @@ FRESULT f_mount ( #if FF_FS_REENTRANT /* Discard mutex of the current volume */ ff_mutex_delete(vol); #endif +#if FF_USE_DYN_BUFFER + if (cfs->fs_type) /* Check if the buffer was ever allocated */ + ff_memfree(cfs->win); /* Deallocate buffer allocated for the filesystem object */ +#endif cfs->fs_type = 0; /* Invalidate the filesystem object to be unregistered */ } @@ -3868,7 +3879,19 @@ FRESULT f_open ( fp->fptr = 0; /* Set file pointer top of the file */ #if !FF_FS_READONLY #if !FF_FS_TINY - memset(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */ +#if FF_USE_DYN_BUFFER + fp->buf = NULL; + if (res == FR_OK) { + fp->buf = ff_memalloc(SS(fs)); + if (!fp->buf) { + res = FR_NOT_ENOUGH_CORE; /* Not enough memory */ + goto fail; + } + memset(fp->buf, 0, SS(fs)); /* Clear sector buffer */ + } +#else + memset(fp->buf, 0, SS(fs)); /* Clear sector buffer */ +#endif #endif if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ fp->fptr = fp->obj.objsize; /* Offset to seek */ @@ -3901,7 +3924,19 @@ FRESULT f_open ( FREE_NAMBUF(); } - if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */ + if (res != FR_OK) { + fp->obj.fs = 0; /* Invalidate file object on error */ +#if !FF_FS_TINY && FF_USE_DYN_BUFFER + if (fp->buf) { + ff_memfree(fp->buf); + fp->buf = NULL; + } +#endif + } + +#if FF_USE_DYN_BUFFER +fail: +#endif LEAVE_FF(fs, res); } @@ -4235,6 +4270,10 @@ FRESULT f_close ( #else fp->obj.fs = 0; /* Invalidate file object */ #endif +#if !FF_FS_TINY && FF_USE_DYN_BUFFER + ff_memfree(fp->buf); + fp->buf = NULL; +#endif #if FF_FS_REENTRANT unlock_volume(fs, FR_OK); /* Unlock volume */ #endif @@ -5998,7 +6037,11 @@ FRESULT f_mkfs ( } } } - if (sz_vol < 128) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >=128s */ + if (n_fat == 1) { + if (sz_vol < MIN_FAT12_SEC_VOL) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >= MIN_FAT12_SEC_VOLs */ + } else { + if (sz_vol < (MIN_FAT12_SEC_VOL + 1)) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >= (MIN_FAT12_SEC_VOL+1)s */ + } /* Now start to create an FAT volume at b_vol and sz_vol */ @@ -6229,7 +6272,7 @@ FRESULT f_mkfs ( } /* Determine number of clusters and final check of validity of the FAT sub-type */ - if (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ + if (sz_vol < b_data + pau * MIN_FAT12_DATA_SEC - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ n_clst = ((DWORD)sz_vol - sz_rsv - sz_fat * n_fat - sz_dir) / pau; if (fsty == FS_FAT32) { if (n_clst <= MAX_FAT16) { /* Too few clusters for FAT32? */ |
