diff --git a/include/ftl.h b/include/ftl.h index 19e38ed..c03d68e 100644 --- a/include/ftl.h +++ b/include/ftl.h @@ -12,7 +12,7 @@ struct ftl_page_desc { uint32_t subtrees[32]; } __attribute__((packed)); -struct ftl_journal { +struct ftl_map { struct flash_dev *dev; uint32_t head, tail; uint32_t root; @@ -28,10 +28,10 @@ struct ftl_journal { #define FTL_MAX_ATTEMPTS 8 -int ftl_init_journal(struct ftl_journal *j, struct flash_dev *dev); -int ftl_resume_journal(struct ftl_journal *j); -int ftl_write(struct ftl_journal *j, uint32_t addr, const uint8_t *data); -int ftl_read(struct ftl_journal *j, void *data, size_t len, uint32_t va); -int ftl_trim(struct ftl_journal *j, uint32_t va); -uint32_t ftl_get_size(const struct ftl_journal *j); -uint32_t ftl_get_capacity(const struct ftl_journal *j); +int ftl_init_map(struct ftl_map *map, struct flash_dev *dev); +int ftl_resume_map(struct ftl_map *map); +int ftl_write(struct ftl_map *map, uint32_t addr, const uint8_t *data); +int ftl_read(struct ftl_map *map, void *data, size_t len, uint32_t va); +int ftl_trim(struct ftl_map *map, uint32_t va); +uint32_t ftl_get_size(const struct ftl_map *map); +uint32_t ftl_get_capacity(const struct ftl_map *map); diff --git a/source/ftl/ftl.c b/source/ftl/ftl.c index d0ce49f..04fa623 100644 --- a/source/ftl/ftl.c +++ b/source/ftl/ftl.c @@ -12,12 +12,12 @@ #include "gc.h" #include "map.h" -int ftl_read(struct ftl_journal *j, void *data, size_t len, uint32_t va) +int ftl_read(struct ftl_map *map, void *data, size_t len, uint32_t va) { int ret; uint32_t page; - if ((ret = trace_path(j, NULL, &page, va)) < 0) { + if ((ret = trace_path(map, NULL, &page, va)) < 0) { memset(data, 0, len); return ret; } @@ -25,46 +25,46 @@ int ftl_read(struct ftl_journal *j, void *data, size_t len, uint32_t va) if (!data) return 0; - return flash_read(j->dev, page << j->log2_page_size, data, - min(j->log2_page_size, len)); + return flash_read(map->dev, page << map->log2_page_size, data, + min(map->log2_page_size, len)); } -int ftl_write(struct ftl_journal *j, uint32_t va, const uint8_t *data) +int ftl_write(struct ftl_map *map, uint32_t va, const uint8_t *data) { struct ftl_page_desc page_desc; int ret; - if (va >= ftl_get_capacity(j) && - !is_aligned(va, 1 << j->log2_page_size)) + if (va >= ftl_get_capacity(map) && + !is_aligned(va, 1 << map->log2_page_size)) return -1; - if ((ret = trace_path(j, &page_desc, NULL, va)) < 0 && + if ((ret = trace_path(map, &page_desc, NULL, va)) < 0 && ret != -ERR_NOT_FOUND) return -1; if (ret == -ERR_NOT_FOUND) - ++j->nused_pages; + ++map->nused_pages; - page_desc.nused_pages = j->nused_pages; + page_desc.nused_pages = map->nused_pages; - return write_upage(j, data, &page_desc); + return write_upage(map, data, &page_desc); } -int ftl_trim(struct ftl_journal *j, uint32_t va) +int ftl_trim(struct ftl_map *map, uint32_t va) { struct ftl_page_desc page_desc, alt_page_desc; size_t level, i; uint32_t alt_va, page; int ret; - if ((ret = trace_path(j, &page_desc, &page, va)) < 0) { + if ((ret = trace_path(map, &page_desc, &page, va)) < 0) { if (ret == -ERR_NOT_FOUND) return 0; return ret; } - --j->nused_pages; + --map->nused_pages; for (i = 0; i < 32; ++i) { level = 32 - i - 1; @@ -74,45 +74,45 @@ int ftl_trim(struct ftl_journal *j, uint32_t va) } if (i == 32) { - j->root = UINT32_MAX; + map->root = UINT32_MAX; memset(&page_desc, 0xff, sizeof page_desc); page_desc.nused_pages = 0; - return write_upage(j, NULL, &page_desc); + return write_upage(map, NULL, &page_desc); } - if (read_page_desc(j, &alt_page_desc, alt_va) < 0) + if (read_page_desc(map, &alt_page_desc, alt_va) < 0) return -1; page_desc.va = alt_page_desc.va; - page_desc.nused_pages = j->nused_pages; + page_desc.nused_pages = map->nused_pages; page_desc.subtrees[level] = UINT32_MAX; for (i = level + 1; i < 32; ++i) { page_desc.subtrees[i] = alt_page_desc.subtrees[i]; } - if (flash_copy(j->dev, j->head << j->log2_page_size, - page << j->log2_page_size, 1 << j->log2_page_size) < 0) + if (flash_copy(map->dev, map->head << map->log2_page_size, + page << map->log2_page_size, 1 << map->log2_page_size) < 0) return -1; - return write_upage(j, NULL, &page_desc); + return write_upage(map, NULL, &page_desc); } /* Returns the amount of used pages with a unique virtual address multiplied by * the page size as the size of used space on the device. */ -uint32_t ftl_get_size(const struct ftl_journal *j) +uint32_t ftl_get_size(const struct ftl_map *map) { - return j->nused_pages << j->log2_page_size; + return map->nused_pages << map->log2_page_size; } /* The capacity of the device is the total amount of user pages minus a block * worth of user pages for garbage collection. */ -uint32_t ftl_get_capacity(const struct ftl_journal *j) +uint32_t ftl_get_capacity(const struct ftl_map *map) { - return ((j->nblocks - 1) << j->log2_block_size) - - ((j->nblocks - 1) << j->log2_page_size); + return ((map->nblocks - 1) << map->log2_block_size) - + ((map->nblocks - 1) << map->log2_page_size); } diff --git a/source/ftl/gc.c b/source/ftl/gc.c index 4d458bc..365fb84 100644 --- a/source/ftl/gc.c +++ b/source/ftl/gc.c @@ -4,11 +4,11 @@ #include "gc.h" -int read_page_desc(struct ftl_journal *j, +int read_page_desc(struct ftl_map *map, struct ftl_page_desc *page_desc, uint32_t upage); -int trace_path(struct ftl_journal *j, +int trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, uint32_t *loc, uint32_t va); -int write_upage(struct ftl_journal *j, const uint8_t *page, +int write_upage(struct ftl_map *map, const uint8_t *page, const struct ftl_page_desc *page_desc); /* For a given user page, attempt to claim more free space by checking if no @@ -17,43 +17,43 @@ int write_upage(struct ftl_journal *j, const uint8_t *page, * the page by copying the page to create a new mapping such that the old page * can be ignored and erased. */ -static int free_page(struct ftl_journal *j, uint32_t upage) +static int free_page(struct ftl_map *map, uint32_t upage) { struct ftl_page_desc page_desc; uint32_t found_upage, va; - if (read_page_desc(j, &page_desc, upage) < 0) + if (read_page_desc(map, &page_desc, upage) < 0) return -1; va = page_desc.va; - if (trace_path(j, &page_desc, &found_upage, va) < 0) + if (trace_path(map, &page_desc, &found_upage, va) < 0) return -1; if (upage != found_upage) return 0; - page_desc.nused_pages = j->nused_pages; + page_desc.nused_pages = map->nused_pages; - if (flash_copy(j->dev, j->head << j->log2_page_size, - upage << j->log2_page_size, 1 << j->log2_page_size) < 0) + if (flash_copy(map->dev, map->head << map->log2_page_size, + upage << map->log2_page_size, 1 << map->log2_page_size) < 0) return -1; - return write_upage(j, NULL, &page_desc); + return write_upage(map, NULL, &page_desc); } /* Claim more free space by checking which user pages in a page group are * mapped and for which the mappings have been obsoleted by a more recent * mapping. The mapped user pages are preserved by copying. */ -static int free_group(struct ftl_journal *j, uint32_t group) +static int free_group(struct ftl_map *map, uint32_t group) { - uint32_t npages = UINT32_C(1) << j->log2_pages_per_group; - uint32_t page = group << j->log2_pages_per_group; + uint32_t npages = UINT32_C(1) << map->log2_pages_per_group; + uint32_t page = group << map->log2_pages_per_group; uint32_t i; for (i = 0; i < npages; ++i) { - if (free_page(j, page + i) < 0) + if (free_page(map, page + i) < 0) return -1; } @@ -64,14 +64,14 @@ static int free_group(struct ftl_journal *j, uint32_t group) * for which the mappings have been obsoleted by a more recent mapping. The * mapped user pages are preserved by copying. */ -static int free_block(struct ftl_journal *j, uint32_t block) +static int free_block(struct ftl_map *map, uint32_t block) { - uint32_t ngroups = UINT32_C(1) << j->log2_groups_per_block; - uint32_t group = block << j->log2_groups_per_block; + uint32_t ngroups = UINT32_C(1) << map->log2_groups_per_block; + uint32_t group = block << map->log2_groups_per_block; uint32_t i; for (i = 0; i < ngroups; ++i) { - if (free_group(j, group + i) < 0) + if (free_group(map, group + i) < 0) return -1; } @@ -83,28 +83,28 @@ static int free_block(struct ftl_journal *j, uint32_t block) * newer pages have obsoleted the mapping. Further, we move the user pages that * are still mapped as these should be preserved. */ -static int free_tail(struct ftl_journal *j) +static int free_tail(struct ftl_map *map) { - size_t log2_pages_per_block = j->log2_pages_per_group + - j->log2_groups_per_block; - size_t npages = j->nblocks << log2_pages_per_block; + size_t log2_pages_per_block = map->log2_pages_per_group + + map->log2_groups_per_block; + size_t npages = map->nblocks << log2_pages_per_block; size_t dist; - if (j->head < j->tail) - dist = j->tail - j->head; + if (map->head < map->tail) + dist = map->tail - map->head; else - dist = npages - j->head + j->tail; + dist = npages - map->head + map->tail; if (dist > (UINT32_C(1) << log2_pages_per_block)) return 0; - if (free_block(j, j->tail >> log2_pages_per_block) < 0) + if (free_block(map, map->tail >> log2_pages_per_block) < 0) return -1; - j->tail += 1 << log2_pages_per_block; + map->tail += 1 << log2_pages_per_block; - if (j->tail >= npages) - j->tail -= npages; + if (map->tail >= npages) + map->tail -= npages; return 0; } @@ -114,17 +114,17 @@ static int free_tail(struct ftl_journal *j) * nothing to be done. Otherwise, we free the tail if necessary and erase the * block for writing. */ -int prepare_head(struct ftl_journal *j) +int prepare_head(struct ftl_map *map) { - size_t log2_pages_per_block = j->log2_pages_per_group + - j->log2_groups_per_block; + size_t log2_pages_per_block = map->log2_pages_per_group + + map->log2_groups_per_block; - if (!is_aligned(j->head, log2_pages_per_block)) + if (!is_aligned(map->head, log2_pages_per_block)) return 0; - if (free_tail(j) < 0) + if (free_tail(map) < 0) return -1; - return flash_erase(j->dev, j->head >> log2_pages_per_block, - j->log2_block_size); + return flash_erase(map->dev, map->head >> log2_pages_per_block, + map->log2_block_size); } diff --git a/source/ftl/gc.h b/source/ftl/gc.h index a4de37d..f56fdcc 100644 --- a/source/ftl/gc.h +++ b/source/ftl/gc.h @@ -1,3 +1,3 @@ #pragma once -int prepare_head(struct ftl_journal *j); +int prepare_head(struct ftl_map *map); diff --git a/source/ftl/map.c b/source/ftl/map.c index e85cbca..10e26f0 100644 --- a/source/ftl/map.c +++ b/source/ftl/map.c @@ -12,16 +12,16 @@ /* Given a page number, this function checks whether the page is fully erased * by checking if all bits are set to ones. */ -static int is_page_erased(struct ftl_journal *j, uint32_t page) +static int is_page_erased(struct ftl_map *map, uint32_t page) { uint8_t data[64]; - size_t i, nbytes, len = j->log2_page_size; - uint32_t addr = page << j->log2_page_size; + size_t i, nbytes, len = map->log2_page_size; + uint32_t addr = page << map->log2_page_size; while (len) { nbytes = min(sizeof data, len); - if (flash_read(j->dev, addr, data, nbytes) < 0) + if (flash_read(map->dev, addr, data, nbytes) < 0) return 0; for (i = 0; i < nbytes; ++i) { @@ -39,14 +39,14 @@ static int is_page_erased(struct ftl_journal *j, uint32_t page) /* Given the group number, this function checks if a page group is erased by * checking if the pages that compose the page group are erased. */ -static int is_group_erased(struct ftl_journal *j, uint32_t group) +static int is_group_erased(struct ftl_map *map, uint32_t group) { - uint32_t npages = UINT32_C(1) << j->log2_pages_per_group; - uint32_t page = group << j->log2_pages_per_group; + uint32_t npages = UINT32_C(1) << map->log2_pages_per_group; + uint32_t page = group << map->log2_pages_per_group; uint32_t i; for (i = 0; i < npages; ++i) { - if (!is_page_erased(j, page + i)) + if (!is_page_erased(map, page + i)) return 0; } @@ -62,17 +62,17 @@ static int is_group_erased(struct ftl_journal *j, uint32_t group) * possible pages on the devices, the page number of the very first user page * is returned instead. */ -static uint32_t next_upage(struct ftl_journal *j, uint32_t p) +static uint32_t next_upage(struct ftl_map *map, uint32_t p) { - size_t log2_pages_per_block = j->log2_pages_per_group + - j->log2_groups_per_block; + size_t log2_pages_per_block = map->log2_pages_per_group + + map->log2_groups_per_block; ++p; - if (is_aligned(p + 1, j->log2_pages_per_group)) + if (is_aligned(p + 1, map->log2_pages_per_group)) ++p; - if (p >= (j->nblocks << log2_pages_per_block)) + if (p >= (map->nblocks << log2_pages_per_block)) p = 0; return p; @@ -80,71 +80,71 @@ static uint32_t next_upage(struct ftl_journal *j, uint32_t p) /* Reads the header of the given page group. */ -int read_page_group(struct ftl_journal *j, +int read_page_group(struct ftl_map *map, struct ftl_page_group *group, uint32_t group_no) { uint32_t page, addr; - page = ((group_no + 1) << j->log2_pages_per_group) - 1; - addr = page << j->log2_page_size; + page = ((group_no + 1) << map->log2_pages_per_group) - 1; + addr = page << map->log2_page_size; - return flash_read(j->dev, addr, group, sizeof *group); + return flash_read(map->dev, addr, group, sizeof *group); } /* Given the page number of a user page, reads the page descriptor associated * with the user page by locating the footer and more specifically the page * descriptor within the page group. */ -int read_page_desc(struct ftl_journal *j, +int read_page_desc(struct ftl_map *map, struct ftl_page_desc *page_desc, uint32_t upage) { uint32_t group_no, page, addr, offset; - group_no = upage >> j->log2_pages_per_group; - page = ((group_no + 1) << j->log2_pages_per_group) - 1; - addr = page << j->log2_page_size; + group_no = upage >> map->log2_pages_per_group; + page = ((group_no + 1) << map->log2_pages_per_group) - 1; + addr = page << map->log2_page_size; offset = sizeof(struct ftl_page_group) + - (upage & ((1 << j->log2_pages_per_group) - 1)) * sizeof *page_desc; + (upage & ((1 << map->log2_pages_per_group) - 1)) * sizeof *page_desc; - return flash_read(j->dev, addr + offset, page_desc, sizeof *page_desc); + return flash_read(map->dev, addr + offset, page_desc, sizeof *page_desc); } /* Writes the page descriptor to the footer of the current page group and * increments the head to point to the next free user page. */ -static int write_page_desc(struct ftl_journal *j, +static int write_page_desc(struct ftl_map *map, const struct ftl_page_desc *page_desc) { struct ftl_page_group group; uint32_t group_no, page, addr, offset, head; - group_no = j->head >> j->log2_pages_per_group; - page = ((group_no + 1) << j->log2_pages_per_group) - 1; - addr = page << j->log2_page_size; + group_no = map->head >> map->log2_pages_per_group; + page = ((group_no + 1) << map->log2_pages_per_group) - 1; + addr = page << map->log2_page_size; /* Write the page group header. */ - if (is_page_erased(j, page)) { + if (is_page_erased(map, page)) { memcpy(&group.magic, "FTL", sizeof group.magic); - group.epoch = j->epoch; - group.tail = j->tail; + group.epoch = map->epoch; + group.tail = map->tail; - if (flash_write(j->dev, addr, &group, sizeof group) < 0) + if (flash_write(map->dev, addr, &group, sizeof group) < 0) return -1; } - offset = sizeof group + (j->head & ((1 << j->log2_pages_per_group) - 1)) * + offset = sizeof group + (map->head & ((1 << map->log2_pages_per_group) - 1)) * sizeof *page_desc; - if (flash_write(j->dev, addr + offset, page_desc, sizeof *page_desc) < 0) + if (flash_write(map->dev, addr + offset, page_desc, sizeof *page_desc) < 0) return -1; - j->root = j->head; + map->root = map->head; - head = j->head; - j->head = next_upage(j, j->head); + head = map->head; + map->head = next_upage(map, map->head); - if (j->head < head) - ++j->epoch; + if (map->head < head) + ++map->epoch; return 0; } @@ -154,17 +154,17 @@ static int write_page_desc(struct ftl_journal *j, * group, whereupon the head is incremented to point to the next available user * page. */ -int write_upage(struct ftl_journal *j, const uint8_t *page, +int write_upage(struct ftl_map *map, const uint8_t *page, const struct ftl_page_desc *page_desc) { - if (prepare_head(j) < 0) + if (prepare_head(map) < 0) return -1; - if (page && flash_write(j->dev, j->head << j->log2_page_size, page, - j->log2_page_size) < 0) + if (page && flash_write(map->dev, map->head << map->log2_page_size, page, + map->log2_page_size) < 0) return -1; - return write_page_desc(j, page_desc); + return write_page_desc(map, page_desc); } /* Determines the amount of user pages to store in a page group by determining @@ -175,25 +175,25 @@ int write_upage(struct ftl_journal *j, const uint8_t *page, * can also be determined, as a single page group may not cover a whole erase * block. */ -static int find_block_div(struct ftl_journal *j) +static int find_block_div(struct ftl_map *map) { - size_t log2_pages_per_block = j->log2_block_size - j->log2_page_size; - size_t nbytes_avail = (1 << j->log2_page_size) - + size_t log2_pages_per_block = map->log2_block_size - map->log2_page_size; + size_t nbytes_avail = (1 << map->log2_page_size) - sizeof(struct ftl_page_group); size_t nbytes = sizeof(struct ftl_page_desc); - j->log2_pages_per_group = 1; + map->log2_pages_per_group = 1; - while (j->log2_pages_per_group < log2_pages_per_block) { + while (map->log2_pages_per_group < log2_pages_per_block) { nbytes = 2 * nbytes + sizeof(struct ftl_page_desc); if (nbytes > nbytes_avail) break; - ++j->log2_pages_per_group; + ++map->log2_pages_per_group; } - j->log2_groups_per_block = log2_pages_per_block - j->log2_pages_per_group; + map->log2_groups_per_block = log2_pages_per_block - map->log2_pages_per_group; return 0; } @@ -203,18 +203,18 @@ static int find_block_div(struct ftl_journal *j) * use, as a block can only be erased as a whole. Therefore, if the first page * group is not in use, neither will the other page groups in a block. */ -static int find_block(struct ftl_journal *j, struct ftl_page_group *group, +static int find_block(struct ftl_map *map, struct ftl_page_group *group, uint32_t *where, uint32_t block) { uint32_t page; unsigned attempt; - for (attempt = 0; block < j->nblocks && attempt < FTL_MAX_ATTEMPTS; + for (attempt = 0; block < map->nblocks && attempt < FTL_MAX_ATTEMPTS; ++attempt, ++block) { - page = block << j->log2_block_size; - page |= ((UINT32_C(1) << j->log2_pages_per_group) - 1) << j->log2_page_size; + page = block << map->log2_block_size; + page |= ((UINT32_C(1) << map->log2_pages_per_group) - 1) << map->log2_page_size; - if (flash_read(j->dev, page, group, sizeof *group) < 0) + if (flash_read(map->dev, page, group, sizeof *group) < 0) continue; if (memcmp(group->magic, "FTL", sizeof group->magic) != 0) @@ -231,17 +231,17 @@ static int find_block(struct ftl_journal *j, struct ftl_page_group *group, /* Given the block number of the first block, attempts to use binary search to * find the last block that is in use. */ -static uint32_t find_last_block(struct ftl_journal *j, uint32_t first) +static uint32_t find_last_block(struct ftl_map *map, uint32_t first) { struct ftl_page_group group; - uint32_t mid, low = first, high = j->nblocks - 1; + uint32_t mid, low = first, high = map->nblocks - 1; uint32_t found, next; while (low <= high) { mid = (low + high) / 2; - if (find_block(j, &group, &found, mid) < 0 || - group.epoch != j->epoch) { + if (find_block(map, &group, &found, mid) < 0 || + group.epoch != map->epoch) { if (!mid) return first; @@ -250,9 +250,9 @@ static uint32_t find_last_block(struct ftl_journal *j, uint32_t first) continue; } - if (((found + 1) > j->nblocks) || - find_block(j, &group, &next, found + 1) < 0 || - group.epoch != j->epoch) + if (((found + 1) > map->nblocks) || + find_block(map, &group, &next, found + 1) < 0 || + group.epoch != map->epoch) return found; low = next; @@ -264,41 +264,41 @@ static uint32_t find_last_block(struct ftl_journal *j, uint32_t first) /* Attempts to find the last page group that is in use within a block by * performing a binary search on the page groups. */ -static uint32_t find_last_group(struct ftl_journal *j, uint32_t block) +static uint32_t find_last_group(struct ftl_map *map, uint32_t block) { - uint32_t ngroups = UINT32_C(1) << j->log2_groups_per_block; + uint32_t ngroups = UINT32_C(1) << map->log2_groups_per_block; uint32_t mid, low = 0, high = ngroups - 1; while (low <= high) { mid = (low + high) / 2; - if (is_group_erased(j, mid)) { + if (is_group_erased(map, mid)) { high = mid - 1; continue; } if (((mid + 1) >= ngroups) || - is_group_erased(j, mid + 1)) - return (block << j->log2_groups_per_block) + mid; + is_group_erased(map, mid + 1)) + return (block << map->log2_groups_per_block) + mid; low = mid + 1; } - return block << j->log2_groups_per_block; + return block << map->log2_groups_per_block; } -static int find_root(struct ftl_journal *j, uint32_t group) +static int find_root(struct ftl_map *map, uint32_t group) { struct ftl_page_desc page_desc; uint32_t upage; - upage = group << j->log2_pages_per_group; + upage = group << map->log2_pages_per_group; do { - j->root = upage; - upage = next_upage(j, upage); + map->root = upage; + upage = next_upage(map, upage); - if (read_page_desc(j, &page_desc, upage) < 0) + if (read_page_desc(map, &page_desc, upage) < 0) return -1; } while (page_desc.va != UINT32_MAX || page_desc.nused_pages == 0); @@ -311,86 +311,86 @@ static int find_root(struct ftl_journal *j, uint32_t group) * within the page group, the first user page of the next page group should be * used as that page group should not be in use. */ -static int find_head(struct ftl_journal *j) +static int find_head(struct ftl_map *map) { - size_t log2_pages_per_block = j->log2_pages_per_group + - j->log2_groups_per_block; + size_t log2_pages_per_block = map->log2_pages_per_group + + map->log2_groups_per_block; - j->head = j->root; + map->head = map->root; do { - j->head = next_upage(j, j->head); + map->head = next_upage(map, map->head); - if (is_aligned(j->head, log2_pages_per_block)) + if (is_aligned(map->head, log2_pages_per_block)) return 0; - } while (!is_page_erased(j, j->head)); + } while (!is_page_erased(map, map->head)); return 0; } -static void reset_journal(struct ftl_journal *j) +static void reset_map(struct ftl_map *map) { - j->log2_erase_size = ilog2(4 * KIB); - j->log2_page_size = ilog2(4 * KIB); - j->log2_block_size = ilog2(64 * KIB); + map->log2_erase_size = ilog2(4 * KIB); + map->log2_page_size = ilog2(4 * KIB); + map->log2_block_size = ilog2(64 * KIB); - find_block_div(j); + find_block_div(map); - j->nblocks = flash_get_size(j->dev) >> j->log2_block_size; + map->nblocks = flash_get_size(map->dev) >> map->log2_block_size; - j->head = 0; - j->tail = 0; - j->root = UINT32_MAX; - j->nused_pages = 0; - j->epoch = 0; + map->head = 0; + map->tail = 0; + map->root = UINT32_MAX; + map->nused_pages = 0; + map->epoch = 0; } -int ftl_init_journal(struct ftl_journal *j, struct flash_dev *dev) +int ftl_init_map(struct ftl_map *map, struct flash_dev *dev) { - j->dev = dev; + map->dev = dev; - reset_journal(j); + reset_map(map); return 0; } -/* Resumes the journal by finding the first block that is in use, the last +/* Resumes the map by finding the first block that is in use, the last * block that is in use, the last page group that is in use, and setting the * head to the first free user page. */ -int ftl_resume_journal(struct ftl_journal *j) +int ftl_resume_map(struct ftl_map *map) { struct ftl_page_group group; struct ftl_page_desc page_desc; uint32_t first, last, group_no; - if (!j) + if (!map) return -1; - if (find_block(j, &group, &first, 0) < 0) { - reset_journal(j); + if (find_block(map, &group, &first, 0) < 0) { + reset_map(map); return -1; } - j->epoch = group.epoch; - last = find_last_block(j, first); - group_no = find_last_group(j, last); + map->epoch = group.epoch; + last = find_last_block(map, first); + group_no = find_last_group(map, last); - if (find_root(j, group_no) < 0) + if (find_root(map, group_no) < 0) return -1; - if (find_head(j) < 0) + if (find_head(map) < 0) return -1; - if (read_page_group(j, &group, j->root >> j->log2_pages_per_group) < 0) + if (read_page_group(map, &group, map->root >> map->log2_pages_per_group) < 0) return -1; - if (read_page_desc(j, &page_desc, j->root) < 0) + if (read_page_desc(map, &page_desc, map->root) < 0) return -1; - j->tail = group.tail; - j->nused_pages = page_desc.nused_pages; + map->tail = group.tail; + map->nused_pages = page_desc.nused_pages; return 0; } @@ -401,12 +401,12 @@ int ftl_resume_journal(struct ftl_journal *j) * depth until we have either found that there is no further subtree to * traverse or until we have found the actual user page. */ -int trace_path(struct ftl_journal *j, struct ftl_page_desc *new_page_desc, +int trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, uint32_t *page, uint32_t va) { struct ftl_page_desc page_desc; uint8_t depth = 0; - uint32_t upage = j->root; + uint32_t upage = map->root; if (new_page_desc) new_page_desc->va = va; @@ -414,7 +414,7 @@ int trace_path(struct ftl_journal *j, struct ftl_page_desc *new_page_desc, if (upage == UINT32_MAX) goto err_not_found; - if (read_page_desc(j, &page_desc, upage) < 0) + if (read_page_desc(map, &page_desc, upage) < 0) return -1; for (; depth < 32; ++depth) { @@ -436,7 +436,7 @@ int trace_path(struct ftl_journal *j, struct ftl_page_desc *new_page_desc, goto err_not_found; } - if (read_page_desc(j, &page_desc, upage) < 0) + if (read_page_desc(map, &page_desc, upage) < 0) return -1; } diff --git a/source/ftl/map.h b/source/ftl/map.h index 1360983..7a5c0ab 100644 --- a/source/ftl/map.h +++ b/source/ftl/map.h @@ -2,11 +2,11 @@ #define ERR_NOT_FOUND 2 -int read_page_group(struct ftl_journal *j, +int read_page_group(struct ftl_map *map, struct ftl_page_group *group, uint32_t group_no); -int read_page_desc(struct ftl_journal *j, +int read_page_desc(struct ftl_map *map, struct ftl_page_desc *page_desc, uint32_t upage); -int write_upage(struct ftl_journal *j, const uint8_t *page, +int write_upage(struct ftl_map *map, const uint8_t *page, const struct ftl_page_desc *page_desc); -int trace_path(struct ftl_journal *j, struct ftl_page_desc *new_page_desc, +int trace_path(struct ftl_map *map, struct ftl_page_desc *new_page_desc, uint32_t *page, uint32_t va);