From dc6365c7f8ab595e267e6bde62d40de9cc583f58 Mon Sep 17 00:00:00 2001 From: "S.J.R. van Schaik" Date: Mon, 31 Jul 2017 14:17:11 +0200 Subject: [PATCH] ftl: fix bug in root recovery by marking page descriptors with a magic value --- include/ftl.h | 1 + source/ftl/map.c | 17 +++++++++-------- source/ftl/map.h | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/ftl.h b/include/ftl.h index a3b9dd7..7fc2318 100644 --- a/include/ftl.h +++ b/include/ftl.h @@ -9,6 +9,7 @@ struct ftl_page_group { } __attribute__((packed)); struct ftl_page_desc { + char magic[4]; uint32_t va; uint32_t nused_pages; uint32_t subtrees[32]; diff --git a/source/ftl/map.c b/source/ftl/map.c index 374528a..39c6fb3 100644 --- a/source/ftl/map.c +++ b/source/ftl/map.c @@ -77,6 +77,9 @@ int read_page_desc(struct ftl_map *map, if (flash_read(map->dev, addr + offset, page_desc, sizeof *page_desc) == 0) return -1; + if (memcmp(page_desc->magic, "page", sizeof page_desc->magic) != 0) + return -1; + return 0; } @@ -84,7 +87,7 @@ int read_page_desc(struct ftl_map *map, * increments the head to point to the next free user page. */ int write_page_desc(struct ftl_map *map, - const struct ftl_page_desc *page_desc) + struct ftl_page_desc *page_desc) { struct ftl_page_group group; uint32_t group_no, page, addr, offset, head; @@ -106,6 +109,8 @@ int write_page_desc(struct ftl_map *map, offset = sizeof group + (map->head & ((1 << map->log2_pages_per_group) - 1)) * sizeof *page_desc; + memcpy(page_desc->magic, "page", sizeof page_desc->magic); + if (flash_write(map->dev, addr + offset, page_desc, sizeof *page_desc) == 0) return -1; @@ -126,7 +131,7 @@ int write_page_desc(struct ftl_map *map, * page. */ int write_upage(struct ftl_map *map, const void *page, - const struct ftl_page_desc *page_desc) + struct ftl_page_desc *page_desc) { if (prepare_head(map) < 0) return -1; @@ -265,14 +270,10 @@ static int find_root(struct ftl_map *map, uint32_t group) upage = group << map->log2_pages_per_group; - do { + while (read_page_desc(map, &page_desc, upage) == 0) { map->root = upage; upage = next_upage(map, upage); - - if (read_page_desc(map, &page_desc, upage) < 0) - return -1; - } while (page_desc.va != UINT32_MAX || - page_desc.nused_pages == 0); + } return 0; } diff --git a/source/ftl/map.h b/source/ftl/map.h index e171544..ba941b0 100644 --- a/source/ftl/map.h +++ b/source/ftl/map.h @@ -7,8 +7,8 @@ int read_page_group(struct ftl_map *map, int read_page_desc(struct ftl_map *map, struct ftl_page_desc *page_desc, uint32_t upage); int write_page_desc(struct ftl_map *map, - const struct ftl_page_desc *page_desc); + struct ftl_page_desc *page_desc); int write_upage(struct ftl_map *map, const void *page, - const struct ftl_page_desc *page_desc); + struct ftl_page_desc *page_desc); int trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, uint32_t *page, uint32_t va);