fatfs: Do not log from critical sections

Logging in the critical section can result in a deadlock when the logger
is redirected to FATFS.

Closes https://github.com/espressif/esp-idf/issues/1693
This commit is contained in:
Roland Dobai 2018-11-09 14:15:00 +01:00
parent 41caedd0da
commit c4193d5ec1

View File

@ -305,18 +305,18 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
prepend_drive_to_path(fat_ctx, &path, NULL); prepend_drive_to_path(fat_ctx, &path, NULL);
int fd = get_next_fd(fat_ctx); int fd = get_next_fd(fat_ctx);
if (fd < 0) { if (fd < 0) {
_lock_release(&fat_ctx->lock);
ESP_LOGE(TAG, "open: no free file descriptors"); ESP_LOGE(TAG, "open: no free file descriptors");
errno = ENFILE; errno = ENFILE;
fd = -1; return -1;
goto out;
} }
FRESULT res = f_open(&fat_ctx->files[fd], path, fat_mode_conv(flags)); FRESULT res = f_open(&fat_ctx->files[fd], path, fat_mode_conv(flags));
if (res != FR_OK) { if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
file_cleanup(fat_ctx, fd); file_cleanup(fat_ctx, fd);
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res); errno = fresult_to_errno(res);
fd = -1; return -1;
goto out;
} }
// O_APPEND need to be stored because it is not compatible with FA_OPEN_APPEND: // O_APPEND need to be stored because it is not compatible with FA_OPEN_APPEND:
// - FA_OPEN_APPEND means to jump to the end of file only after open() // - FA_OPEN_APPEND means to jump to the end of file only after open()
@ -325,7 +325,6 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
// therefore this flag is stored here (at this VFS level) in order to save // therefore this flag is stored here (at this VFS level) in order to save
// memory. // memory.
fat_ctx->o_append[fd] = (flags & O_APPEND) == O_APPEND; fat_ctx->o_append[fd] = (flags & O_APPEND) == O_APPEND;
out:
_lock_release(&fat_ctx->lock); _lock_release(&fat_ctx->lock);
return fd; return fd;
} }
@ -376,13 +375,13 @@ static int vfs_fat_fsync(void* ctx, int fd)
_lock_acquire(&fat_ctx->lock); _lock_acquire(&fat_ctx->lock);
FIL* file = &fat_ctx->files[fd]; FIL* file = &fat_ctx->files[fd];
FRESULT res = f_sync(file); FRESULT res = f_sync(file);
_lock_release(&fat_ctx->lock);
int rc = 0; int rc = 0;
if (res != FR_OK) { if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res); errno = fresult_to_errno(res);
rc = -1; rc = -1;
} }
_lock_release(&fat_ctx->lock);
return rc; return rc;
} }
@ -393,13 +392,13 @@ static int vfs_fat_close(void* ctx, int fd)
FIL* file = &fat_ctx->files[fd]; FIL* file = &fat_ctx->files[fd];
FRESULT res = f_close(file); FRESULT res = f_close(file);
file_cleanup(fat_ctx, fd); file_cleanup(fat_ctx, fd);
_lock_release(&fat_ctx->lock);
int rc = 0; int rc = 0;
if (res != FR_OK) { if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res); errno = fresult_to_errno(res);
rc = -1; rc = -1;
} }
_lock_release(&fat_ctx->lock);
return rc; return rc;
} }
@ -515,12 +514,12 @@ static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
FIL* pf2 = 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 || pf1 == NULL || pf2 == NULL) { if (buf == NULL || pf1 == NULL || pf2 == NULL) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "alloc failed, pf1=%p, pf2=%p, buf=%p", pf1, pf2, buf); ESP_LOGD(TAG, "alloc failed, pf1=%p, pf2=%p, buf=%p", pf1, pf2, buf);
free(pf1); free(pf1);
free(pf2); free(pf2);
free(buf); free(buf);
errno = ENOMEM; errno = ENOMEM;
_lock_release(&fat_ctx->lock);
return -1; return -1;
} }
res = f_open(pf1, n1, FA_READ | FA_OPEN_EXISTING); res = f_open(pf1, n1, FA_READ | FA_OPEN_EXISTING);
@ -529,11 +528,10 @@ static int vfs_fat_link(void* ctx, const char* n1, const char* n2)
goto fail1; goto fail1;
} }
res = f_open(pf2, n2, FA_WRITE | FA_CREATE_NEW); res = f_open(pf2, n2, FA_WRITE | FA_CREATE_NEW);
_lock_release(&fat_ctx->lock);
if (res != FR_OK) { if (res != FR_OK) {
_lock_release(&fat_ctx->lock);
goto fail2; goto fail2;
} }
_lock_release(&fat_ctx->lock);
size_t size_left = f_size(pf1); 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;
@ -768,6 +766,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
file = (FIL*) calloc(1, sizeof(FIL)); file = (FIL*) calloc(1, sizeof(FIL));
if (file == NULL) { if (file == NULL) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "truncate alloc failed"); ESP_LOGD(TAG, "truncate alloc failed");
errno = ENOMEM; errno = ENOMEM;
ret = -1; ret = -1;
@ -777,6 +776,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
res = f_open(file, path, FA_WRITE); res = f_open(file, path, FA_WRITE);
if (res != FR_OK) { if (res != FR_OK) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res); errno = fresult_to_errno(res);
ret = -1; ret = -1;
@ -786,6 +786,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
res = f_size(file); res = f_size(file);
if (res < length) { if (res < length) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "truncate does not support extending size"); ESP_LOGD(TAG, "truncate does not support extending size");
errno = EPERM; errno = EPERM;
ret = -1; ret = -1;
@ -794,6 +795,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
res = f_lseek(file, length); res = f_lseek(file, length);
if (res != FR_OK) { if (res != FR_OK) {
_lock_release(&fat_ctx->lock);
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
errno = fresult_to_errno(res); errno = fresult_to_errno(res);
ret = -1; ret = -1;
@ -801,6 +803,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length)
} }
res = f_truncate(file); res = f_truncate(file);
_lock_release(&fat_ctx->lock);
if (res != FR_OK) { if (res != FR_OK) {
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
@ -821,6 +824,5 @@ close:
out: out:
free(file); free(file);
_lock_release(&fat_ctx->lock);
return ret; return ret;
} }