mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-19 14:26:01 -04:00
vfs_fat: allocate FIL structures on the heap in vfs_fat_link
vfs_fat_link opened two files to perform copy operation. File structures were allocated on the stack. When _MAX_SS setting was increased in ffconf.h due to wear levelling feature, the size of these structures increased to ~4k each (~8k total). This exceeds stack size allocated for tasks in most typical cases. This change makes file structures dynamically allocated.
This commit is contained in:
parent
1a73b41b10
commit
d18157e108
@ -424,28 +424,39 @@ static int vfs_fat_unlink(void* ctx, const char *path)
|
|||||||
|
|
||||||
static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
|
static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
|
||||||
{
|
{
|
||||||
prepend_drive_to_path(ctx, n1, n2);
|
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
|
||||||
const size_t copy_buf_size = 4096;
|
_lock_acquire(&fat_ctx->lock);
|
||||||
|
prepend_drive_to_path(fat_ctx, &n1, &n2);
|
||||||
|
const size_t copy_buf_size = fat_ctx->fs.csize;
|
||||||
|
FRESULT res;
|
||||||
|
FIL* pf1 = calloc(1, sizeof(FIL));
|
||||||
|
FIL* pf2 = calloc(1, sizeof(FIL));
|
||||||
void* buf = malloc(copy_buf_size);
|
void* buf = malloc(copy_buf_size);
|
||||||
if (buf == NULL) {
|
if (buf == NULL || pf1 == NULL || pf2 == NULL) {
|
||||||
|
ESP_LOGD(TAG, "alloc failed, pf1=%p, pf2=%p, buf=%p", pf1, pf2, buf);
|
||||||
|
free(pf1);
|
||||||
|
free(pf2);
|
||||||
|
free(buf);
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
_lock_release(&fat_ctx->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
FIL f1;
|
res = f_open(pf1, n1, FA_READ | FA_OPEN_EXISTING);
|
||||||
FRESULT res = f_open(&f1, n1, FA_READ | FA_OPEN_EXISTING);
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
|
_lock_release(&fat_ctx->lock);
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
FIL f2;
|
res = f_open(pf2, n2, FA_WRITE | FA_CREATE_NEW);
|
||||||
res = f_open(&f2, n2, FA_WRITE | FA_CREATE_NEW);
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
|
_lock_release(&fat_ctx->lock);
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
size_t size_left = f_size(&f1);
|
_lock_release(&fat_ctx->lock);
|
||||||
|
size_t size_left = f_size(pf1);
|
||||||
while (size_left > 0) {
|
while (size_left > 0) {
|
||||||
size_t will_copy = (size_left < copy_buf_size) ? size_left : copy_buf_size;
|
size_t will_copy = (size_left < copy_buf_size) ? size_left : copy_buf_size;
|
||||||
size_t read;
|
size_t read;
|
||||||
res = f_read(&f1, buf, will_copy, &read);
|
res = f_read(pf1, buf, will_copy, &read);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
goto fail3;
|
goto fail3;
|
||||||
} else if (read != will_copy) {
|
} else if (read != will_copy) {
|
||||||
@ -453,7 +464,7 @@ static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
|
|||||||
goto fail3;
|
goto fail3;
|
||||||
}
|
}
|
||||||
size_t written;
|
size_t written;
|
||||||
res = f_write(&f2, buf, will_copy, &written);
|
res = f_write(pf2, buf, will_copy, &written);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
goto fail3;
|
goto fail3;
|
||||||
} else if (written != will_copy) {
|
} else if (written != will_copy) {
|
||||||
@ -462,11 +473,12 @@ static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
|
|||||||
}
|
}
|
||||||
size_left -= will_copy;
|
size_left -= will_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail3:
|
fail3:
|
||||||
f_close(&f2);
|
f_close(pf2);
|
||||||
|
free(pf2);
|
||||||
fail2:
|
fail2:
|
||||||
f_close(&f1);
|
f_close(pf1);
|
||||||
|
free(pf1);
|
||||||
fail1:
|
fail1:
|
||||||
free(buf);
|
free(buf);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
|
Loading…
Reference in New Issue
Block a user