#34348·ardupilot

AP_Logger: stale FAT32 FSINFO free-cluster count silently disables all SD card logging

Author: andresikoCreated Sep 9, 2026Updated Sep 12, 2026

Summary

A FAT32 SD card whose FSINFO free-cluster count has gone stale after an unclean power-off is reported as "out of space" by f_getfree() even though the card is nearly empty. AP_Logger_File then refuses to create any new log and stops any log in progress. The card reads as perfectly healthy on a PC, so the condition is invisible to the operator.

Environment

ArduCopter 4.6.2, CUAV X7. 16 GB microSD, FAT32, 32 KiB clusters, 497 MB used of 14.83 GB.

What happened

Logging stopped mid-session and no further logs were ever created. LASTLOG.TXT still held the last successful log number. Windows reported 14.34 GB free, and a read-only chkdsk found only a few lost cluster chains — nothing that explains a total logging failure.

Reading the volume's raw sectors showed the cause:

FSINFO, sector 1 (primary)   Free_Count = 255 clusters  ->  8,355,840 bytes
FSINFO, sector 7 (backup)    Free_Count = 0xFFFFFFFF    ->  "unknown"
Free clusters counted by walking the FAT itself: 470,040  ->  14.34 GiB

The backup FSINFO still holds its pristine post-format state, since neither FatFs nor Windows maintains it. Only the primary is updated, and it holds a wrong value.

Why this disables logging

libraries/AP_HAL_ChibiOS/hwdef/common/ffconf.h:

c
#define FF_FS_NOFSINFO   0

With bit 0 clear, FatFs trusts the FSINFO free-cluster count and never scans the FAT. Its only validation is that the value does not exceed the total cluster count, so a value that is too small is accepted silently. f_getfree() therefore returns 8,355,840 bytes.

libraries/AP_Logger/AP_Logger_File.h:

c
static constexpr uint32_t _free_space_min_avail = 8388608; // bytes

libraries/AP_Logger/AP_Logger_File.cpp, in both start_new_log() and io_timer():

c
if (disk_space_avail() < _free_space_min_avail && disk_space() > 0) {
    DEV_PRINTF("Out of space for logging\n");
    ...
}
8,355,840 < 8,388,608

The card misses the threshold by 32,768 bytes, exactly one cluster. Two consequences worth noting:

  • The threshold is a hardcoded constant, so LOG_FILE_MB_FREE has no effect on it.
  • The same check runs in io_timer() once per second, so a log already in progress is stopped as well, not just refused at creation.

Suggested fix

c
#define FF_FS_NOFSINFO   1

Bit 0 makes f_getfree() force a full FAT scan on the first call after mount, which is the remedy the FatFs author documents for precisely this failure: http://elm-chan.org/fsw/ff/doc/config.html

The cost is one FAT scan per mount. Setting the value to 3 would additionally stop trusting the last-allocated-cluster hint, which on this card also pointed into allocated space (Nxt_Free = 237).

Why this may be worth fixing

Reformatting cures it, and that is the advice these reports normally receive, so the underlying cause is never identified. Possibly related: #13144, #16834, and a long tail of "PreArm: Logging failed" forum threads in which the card checks out fine on a PC.