How would you design the storage center?
Here is mine, I would like to have your review, see if I missed anything.
network storage and cache will be added on top of this.
I end up having four entities:
- IO Driver: Collection of block-size IO functions
- FS Driver: FS parsing facility
- IO Device: A physical device entity
- Drive: A partition, "drive letter".
IO driver:
Block-size IO, example are Ramdisk, ATA.
Code: Select all
typedef struct IODRIVER_S {
uint32_t name;
void* opaque;
int (*init) (struct IODRIVER_S* driver);
int (*deinit)(struct IODRIVER_S* driver);
int (*open) (struct IODRIVER_S* driver, struct IODEVICE_S* device, const char* resource, int option);
int (*close) (struct IODRIVER_S* driver, struct IODEVICE_S* device);
int (*ioctl) (struct IODRIVER_S* driver, struct IODEVICE_S* device, int req, ...);
int (*read) (struct IODRIVER_S* driver, struct IODEVICE_S* device, void* buf, off_t block, int nblock);
int (*write) (struct IODRIVER_S* driver, struct IODEVICE_S* device, void* buf, off_t block, int nblock);
} IODRIVER;
FS Driver:
Code: Select all
typedef struct FSDRIVER_S {
uint32_t name;
unsigned int flags;
void* opaque;
int (*probe) (struct FSDRIVER_S* fs, IODEVICE* device, uint8_t* vbr);
int (*open) (struct FSDRIVER_S* fs, IODEVICE* device, FS_FILE* file, const char* path);
int (*close) (struct FSDRIVER_S* fs, IODEVICE* device, FS_FILE* file);
int (*read) (struct FSDRIVER_S* fs, IODEVICE* device, FS_FILE* file, void* buf, off_t offset, size_t nbytes);
int (*write) (struct FSDRIVER_S* fs, IODEVICE* device, FS_FILE* file, void* buf, off_t offset, size_t nbytes);
int (*opendir) (struct FSDRIVER_S* fs, IODEVICE* device, FS_DIR *dir, const char* path);
int (*readdir) (struct FSDRIVER_S* fs, IODEVICE* device, FS_DIR *dir, unsigned int index, FS_DIRENT* dirent );
int (*closedir)(struct FSDRIVER_S* fs, IODEVICE* device, FS_DIR *dir);
// int (*fstat) (struct FSDRIVER* fs, VFS_FILE* file, char* buf);
} FSDRIVER;
iodevice (physical disk) - block IO, work on sector numbers
- name (to identify which device of same type)
- driver:io
- driver-specific information used by io driver
drive - provide unified file operations
- name (use with mount)
- iodevice
- partition (LBA start, size)
- fs driver
- driver-specific information used by fs driver
The initialization sequence is:
- Register *all* IO driver and FS driver, I'm not doing on-demand to add extra complexity
- get a device type and token from device list (eg ATA:0, RAMDISK:2M~4M)
- Resolve an IO driver by device type
- Create an IO Device instant, the device can be accessed by sector IO now.
- Loop all partition for (handle multiple partition or single partition device):
1) Load VBR
2) Pass the VBR to each FS driver by calling fs->probe
3) fs->probe return true if such partition is supported
4) Create a Drive instant.