AsterFS: odolnější serializace uzlů a bezpečnější flush na disk
This commit is contained in:
+55
-17
@@ -38,8 +38,6 @@
|
|||||||
#define ASTERFS_MAGIC "ASTERFS1"
|
#define ASTERFS_MAGIC "ASTERFS1"
|
||||||
#define ASTERFS_VERSION 1U
|
#define ASTERFS_VERSION 1U
|
||||||
|
|
||||||
#define ASTERFS_NODE_BYTES (ASTERFS_NAME_LEN + 1 + 2 + 1 + ASTERFS_DATA_LEN)
|
|
||||||
#define ASTERFS_NODE_SECTORS (((ASTERFS_MAX_FILES * ASTERFS_NODE_BYTES) + 511) / 512)
|
|
||||||
#define ASTERFS_DISK_START_LBA 1U
|
#define ASTERFS_DISK_START_LBA 1U
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -56,7 +54,12 @@ typedef struct {
|
|||||||
u16 size;
|
u16 size;
|
||||||
u8 reserved;
|
u8 reserved;
|
||||||
u8 data[ASTERFS_DATA_LEN];
|
u8 data[ASTERFS_DATA_LEN];
|
||||||
} asterfs_disk_node_t;
|
} __attribute__((packed)) asterfs_disk_node_t;
|
||||||
|
|
||||||
|
#define ASTERFS_NODE_BYTES ((usize)sizeof(asterfs_disk_node_t))
|
||||||
|
#define ASTERFS_NODE_SECTORS (((ASTERFS_MAX_FILES * ASTERFS_NODE_BYTES) + 511) / 512)
|
||||||
|
_Static_assert(sizeof(asterfs_disk_node_t) == (ASTERFS_NAME_LEN + 1 + 2 + 1 + ASTERFS_DATA_LEN),
|
||||||
|
"asterfs_disk_node_t layout mismatch");
|
||||||
|
|
||||||
static asterfs_node_t nodes[ASTERFS_MAX_FILES];
|
static asterfs_node_t nodes[ASTERFS_MAX_FILES];
|
||||||
static int nodes_used = 0;
|
static int nodes_used = 0;
|
||||||
@@ -222,31 +225,39 @@ static void fs_reset_memory(void) {
|
|||||||
nodes_used = 0;
|
nodes_used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fs_encode_nodes(u8 *out) {
|
static void fs_encode_nodes(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ASTERFS_MAX_FILES; ++i) {
|
for (i = 0; i < ASTERFS_MAX_FILES; ++i) {
|
||||||
asterfs_disk_node_t d;
|
asterfs_disk_node_t d;
|
||||||
usize off = (usize)i * ASTERFS_NODE_BYTES;
|
usize off = (usize)i * ASTERFS_NODE_BYTES;
|
||||||
|
|
||||||
|
if (off + ASTERFS_NODE_BYTES > sizeof(g_nodes_blob)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
aster_memset(&d, 0, sizeof(d));
|
aster_memset(&d, 0, sizeof(d));
|
||||||
aster_memcpy(d.name, nodes[i].name, ASTERFS_NAME_LEN);
|
aster_memcpy(d.name, nodes[i].name, ASTERFS_NAME_LEN);
|
||||||
d.is_dir = nodes[i].is_dir;
|
d.is_dir = nodes[i].is_dir;
|
||||||
d.size = nodes[i].size;
|
d.size = nodes[i].size;
|
||||||
aster_memcpy(d.data, nodes[i].data, ASTERFS_DATA_LEN);
|
aster_memcpy(d.data, nodes[i].data, ASTERFS_DATA_LEN);
|
||||||
|
|
||||||
aster_memcpy(out + off, &d, ASTERFS_NODE_BYTES);
|
aster_memcpy(g_nodes_blob + off, &d, ASTERFS_NODE_BYTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fs_decode_nodes(const u8 *in) {
|
static void fs_decode_nodes(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ASTERFS_MAX_FILES; ++i) {
|
for (i = 0; i < ASTERFS_MAX_FILES; ++i) {
|
||||||
asterfs_disk_node_t d;
|
asterfs_disk_node_t d;
|
||||||
usize off = (usize)i * ASTERFS_NODE_BYTES;
|
usize off = (usize)i * ASTERFS_NODE_BYTES;
|
||||||
|
|
||||||
aster_memcpy(&d, in + off, ASTERFS_NODE_BYTES);
|
if (off + ASTERFS_NODE_BYTES > sizeof(g_nodes_blob)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
aster_memcpy(&d, g_nodes_blob + off, ASTERFS_NODE_BYTES);
|
||||||
|
|
||||||
aster_memset(nodes[i].name, 0, ASTERFS_NAME_LEN);
|
aster_memset(nodes[i].name, 0, ASTERFS_NAME_LEN);
|
||||||
aster_memcpy(nodes[i].name, d.name, ASTERFS_NAME_LEN);
|
aster_memcpy(nodes[i].name, d.name, ASTERFS_NAME_LEN);
|
||||||
@@ -287,7 +298,7 @@ static int fs_flush_disk(void) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_encode_nodes(g_nodes_blob);
|
fs_encode_nodes();
|
||||||
for (sector = 0; sector < ASTERFS_NODE_SECTORS; ++sector) {
|
for (sector = 0; sector < ASTERFS_NODE_SECTORS; ++sector) {
|
||||||
usize off = (usize)sector * 512;
|
usize off = (usize)sector * 512;
|
||||||
aster_memset(g_sector_buffer, 0, sizeof(g_sector_buffer));
|
aster_memset(g_sector_buffer, 0, sizeof(g_sector_buffer));
|
||||||
@@ -337,7 +348,7 @@ static int fs_load_disk(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_decode_nodes(g_nodes_blob);
|
fs_decode_nodes();
|
||||||
if (super.nodes_used > ASTERFS_MAX_FILES) {
|
if (super.nodes_used > ASTERFS_MAX_FILES) {
|
||||||
nodes_used = ASTERFS_MAX_FILES;
|
nodes_used = ASTERFS_MAX_FILES;
|
||||||
} else {
|
} else {
|
||||||
@@ -519,7 +530,10 @@ int asterfs_create_file(const char *name) {
|
|||||||
nodes[nodes_used].size = 0;
|
nodes[nodes_used].size = 0;
|
||||||
nodes[nodes_used].is_dir = 0;
|
nodes[nodes_used].is_dir = 0;
|
||||||
++nodes_used;
|
++nodes_used;
|
||||||
(void)fs_flush_disk();
|
if (fs_flush_disk() != 0) {
|
||||||
|
--nodes_used;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +562,10 @@ int asterfs_create_dir(const char *name) {
|
|||||||
nodes[nodes_used].size = 0;
|
nodes[nodes_used].size = 0;
|
||||||
nodes[nodes_used].is_dir = 1;
|
nodes[nodes_used].is_dir = 1;
|
||||||
++nodes_used;
|
++nodes_used;
|
||||||
(void)fs_flush_disk();
|
if (fs_flush_disk() != 0) {
|
||||||
|
--nodes_used;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,7 +587,9 @@ int asterfs_remove_file(const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
--nodes_used;
|
--nodes_used;
|
||||||
(void)fs_flush_disk();
|
if (fs_flush_disk() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,7 +622,9 @@ int asterfs_remove_dir(const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
--nodes_used;
|
--nodes_used;
|
||||||
(void)fs_flush_disk();
|
if (fs_flush_disk() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,13 +651,30 @@ int asterfs_write_file(const char *name, const u8 *data, u16 len) {
|
|||||||
len = ASTERFS_DATA_LEN;
|
len = ASTERFS_DATA_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
aster_memset(nodes[idx].data, 0, ASTERFS_DATA_LEN);
|
{
|
||||||
aster_memcpy(nodes[idx].data, data, len);
|
u8 old_data[ASTERFS_DATA_LEN];
|
||||||
nodes[idx].size = len;
|
u16 old_size = nodes[idx].size;
|
||||||
(void)fs_flush_disk();
|
|
||||||
|
aster_memcpy(old_data, nodes[idx].data, ASTERFS_DATA_LEN);
|
||||||
|
|
||||||
|
aster_memset(nodes[idx].data, 0, ASTERFS_DATA_LEN);
|
||||||
|
aster_memcpy(nodes[idx].data, data, len);
|
||||||
|
nodes[idx].size = len;
|
||||||
|
|
||||||
|
if (fs_flush_disk() != 0) {
|
||||||
|
aster_memcpy(nodes[idx].data, old_data, ASTERFS_DATA_LEN);
|
||||||
|
nodes[idx].size = old_size;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int asterfs_sync(void) {
|
||||||
|
return fs_flush_disk();
|
||||||
|
}
|
||||||
|
|
||||||
int asterfs_read_file(const char *name, u8 *out, u16 max_len) {
|
int asterfs_read_file(const char *name, u8 *out, u16 max_len) {
|
||||||
int idx;
|
int idx;
|
||||||
u16 len;
|
u16 len;
|
||||||
|
|||||||
Reference in New Issue
Block a user