Hello!
Seemingly, there is an issue with file deletion in ITS. I would think it is not
possible to delete the last object in a data block (so that the data
block becomes empty).
It’s easiest to reproduce with using large objects (because then the number of
involved objects is small), but would also happen with multiple
smaller objects:
With the following flash configuration:
ITS_MAX_ASSET_SIZE=0x1000
TFM_HAL_ITS_SECTORS_PER_BLOCK=1
TFM_HAL_ITS_FLASH_AREA_SIZE=0x20000
TFM_HAL_ITS_PROGRAM_UNIT=0x100
ITS_FLASH_NAND_BUF_SIZE=1*0x1000
In a sequence of writing and deleting an object like:
const uint8_t big_file[ITS_MAX_ASSET_SIZE] = {0};
status = psa_its_set(uid, sizeof(big_file), big_file, flags);
status = psa_its_remove(uid);
deleting the file fails with the status of PSA_ERROR_GENERIC_ERROR.
What I think happens is:
Due to the size of the file, it does not fit in the metadata block, and is put a
second (data only) block. The object is written there as expected.
When the data block is deleted later, an attempt is being made to compact it
with its_flash_fs_dblock_compact_block(). However, there is no data to keep
before the object to be deleted and also no data to keep after it, this block
will become empty, so no call to its_flash_fs_block_to_block_move() happens,
which causes no call to fs_ctx->ops->write() happens. Now the flash driver in
my case is a buffering its_flash_nand.c. In the write() call it would associate
a buffer for the physical sector to write. But since there is no write() call
the subsequent fs_ctx->ops->flush() fails as it has no buffer to flush out.
I believe no compaction of the block should even be attempted - it is known
that the block will be empty beforehand. Perhaps similar to
https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/17578, this is
yet another reason to skip compacting of the block?
It would be very much appreciated if one of the experts could confirm this
suspicious behavior or point out a mistake I am making.
Thank you very much, best regards
Stefan Krug