summaryrefslogtreecommitdiff
path: root/lib/fatfs/src/ff.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/fatfs/src/ff.c')
-rw-r--r--lib/fatfs/src/ff.c59
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? */