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