Storage architecture discussion

Current Design Target


Four NAND Volume States

The state of the NAND volume may exist in one of the following four states:

typedef enum _nand_volume_state_t {
    NAND_VOLUME_STATE_EJECTED = 0,
    NAND_VOLUME_STATE_SHARED_READONLY,
    NAND_VOLUME_STATE_FW_EXCLUSIVE,
    NAND_VOLUME_STATE_HOST_EXCLUSIVE,
} nand_volume_state_t;

In addition, there is a MediaChangeNotification flag, which stores whether the host must see a sequence of Sense/ASC/ASCQ errors when it tries to access the volume.


State Transition Table

from \ to ejected shared R/O FW Exc Host Exc
ejected Y M Y M
shared R/O Y Y Y M
FW Exc Y M Y M
Host Exc Y X Y Y

Where M indicates allowed, but must set MediaChangeNotification flag.
Where X may not be permitted … to be decided later.


Main Transition Events

Transition to NAND_VOLUME_STATE_FW_EXCLUSIVE, unless media is ejected (e.g., in process of formatting, mounting, …):

  • nand/nand/ftl_diskio.c / diskio_write()

When calling f_close(), check if the handle being closed is a write-capable handle. If so, and this is the final write-capable handle being closed:

  • Assert state is NAND_VOLUME_STATE_FW_EXCLUSIVE and transition to state NAND_VOLUME_STATE_SHARED_RO

Non-FileHandle Events

The following FW APIs do not use a file handle, but may change the media state. Therefore, they should set the MediaChangeNotification flag explicitly on success. Note that it’s safe to set this flag even if the host is not permitted to access the volume:

  • f_mkdir()
  • f_unlink()
  • f_rename()
  • f_chmod()
  • f_setlabel()

Events to be specially handled

The following change the volume state at a fundamental level. Transition to NAND_VOLUME_STATE_SHARED_RO AND set MediaChangeNotification:

  • f_mkfs()
  • f_mount()
  • f_fdisk()

Assertions to help validate correctness

The following APIs each require the use of a write-capable file handle. To help catch any missed edge cases, assert that state ends up as NAND_VOLUME_STATE_FW_EXCLUSIVE
for successful calls to:

  • f_write()
  • f_truncate()
  • f_sync()
  • f_forward()
  • f_expand()
  • f_putc()
  • f_puts()
  • f_printf()

It seems this is doable, and that it will require careful review to ensure all edge cases are caught. However, the user experience should be quite friendly.

3 Likes