vfs: restrict the fast seek for read-only files

Since the files under fast-seek cannot be expanded with further writes, it does not
make sense to enable fast-seek which may fail in write-mode files
This commit is contained in:
Felipe Neves
2020-10-26 16:06:12 -03:00
parent 32e760adfb
commit 93ffc009ef
3 changed files with 49 additions and 25 deletions

View File

@@ -217,11 +217,27 @@ void test_fatfs_lseek(const char* filename)
TEST_ASSERT_EQUAL(18, ftell(f));
TEST_ASSERT_EQUAL(0, fseek(f, 0, SEEK_SET));
char buf[20];
TEST_ASSERT_EQUAL(18, fread(buf, 1, sizeof(buf), f));
const char ref_buf[] = "0123456789\n\0\0\0abc\n";
TEST_ASSERT_EQUAL_INT8_ARRAY(ref_buf, buf, sizeof(ref_buf) - 1);
TEST_ASSERT_EQUAL(0, fclose(f));
#ifdef CONFIG_FATFS_USE_FASTSEEK
f = fopen(filename, "rb+");
TEST_ASSERT_NOT_NULL(f);
TEST_ASSERT_EQUAL(0, fseek(f, 0, SEEK_END));
TEST_ASSERT_EQUAL(18, ftell(f));
TEST_ASSERT_EQUAL(0, fseek(f, -4, SEEK_CUR));
TEST_ASSERT_EQUAL(14, ftell(f));
TEST_ASSERT_EQUAL(0, fseek(f, -14, SEEK_CUR));
TEST_ASSERT_EQUAL(0, ftell(f));
TEST_ASSERT_EQUAL(18, fread(buf, 1, sizeof(buf), f));
TEST_ASSERT_EQUAL_INT8_ARRAY(ref_buf, buf, sizeof(ref_buf) - 1);
TEST_ASSERT_EQUAL(0, fclose(f));
#endif
}
void test_fatfs_truncate_file(const char* filename)

View File

@@ -319,27 +319,33 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
#ifdef CONFIG_FATFS_USE_FASTSEEK
FIL* file = &fat_ctx->files[fd];
DWORD *clmt_mem = ff_memalloc(sizeof(DWORD) * CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE);
if (clmt_mem == NULL) {
f_close(file);
file_cleanup(fat_ctx, fd);
_lock_release(&fat_ctx->lock);
ESP_LOGE(TAG, "open: Failed to pre-allocate CLMT buffer for fast-seek");
errno = ENOMEM;
return -1;
}
//fast-seek is only allowed in read mode, since file cannot be expanded
//to use it.
if(!(fat_mode_conv(flags) & (FA_WRITE))) {
DWORD *clmt_mem = ff_memalloc(sizeof(DWORD) * CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE);
if (clmt_mem == NULL) {
f_close(file);
file_cleanup(fat_ctx, fd);
_lock_release(&fat_ctx->lock);
ESP_LOGE(TAG, "open: Failed to pre-allocate CLMT buffer for fast-seek");
errno = ENOMEM;
return -1;
}
file->cltbl = clmt_mem;
file->cltbl[0] = CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE;
res = f_lseek(file, CREATE_LINKMAP);
ESP_LOGD(TAG, "%s: fast-seek has: %s",
__func__,
(res == FR_OK) ? "activated" : "failed");
if(res != FR_OK) {
ESP_LOGW(TAG, "%s: fast-seek not activated reason code: %d",
__func__, res);
//If linkmap creation fails, fallback to the non fast seek.
ff_memfree(file->cltbl);
file->cltbl = clmt_mem;
file->cltbl[0] = CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE;
res = f_lseek(file, CREATE_LINKMAP);
ESP_LOGD(TAG, "%s: fast-seek has: %s",
__func__,
(res == FR_OK) ? "activated" : "failed");
if(res != FR_OK) {
ESP_LOGW(TAG, "%s: fast-seek not activated reason code: %d",
__func__, res);
//If linkmap creation fails, fallback to the non fast seek.
ff_memfree(file->cltbl);
file->cltbl = NULL;
}
} else {
file->cltbl = NULL;
}
#endif
@@ -404,6 +410,7 @@ static ssize_t vfs_fat_pread(void *ctx, int fd, void *dst, size_t size, off_t of
const off_t prev_pos = f_tell(file);
FRESULT f_res = f_lseek(file, offset);
if (f_res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, f_res);
errno = fresult_to_errno(f_res);
@@ -443,6 +450,7 @@ static ssize_t vfs_fat_pwrite(void *ctx, int fd, const void *src, size_t size, o
const off_t prev_pos = f_tell(file);
FRESULT f_res = f_lseek(file, offset);
if (f_res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, f_res);
errno = fresult_to_errno(f_res);
@@ -497,6 +505,7 @@ static int vfs_fat_close(void* ctx, int fd)
#ifdef CONFIG_FATFS_USE_FASTSEEK
ff_memfree(file->cltbl);
file->cltbl = NULL;
#endif
FRESULT res = f_close(file);
@@ -530,7 +539,6 @@ static off_t vfs_fat_lseek(void* ctx, int fd, off_t offset, int mode)
}
ESP_LOGD(TAG, "%s: offset=%ld, filesize:=%d", __func__, new_pos, f_size(file));
FRESULT res = f_lseek(file, new_pos);
if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);

View File

@@ -328,7 +328,7 @@ component_ut_test_001:
UT_001:
extends: .unit_test_template
parallel: 43
parallel: 44
tags:
- ESP32_IDF
- UT_T1_1
@@ -480,7 +480,7 @@ UT_034:
UT_035:
extends: .unit_test_s2_template
parallel: 44
parallel: 45
tags:
- ESP32S2_IDF
- UT_T1_1