|
|
|
@ -9,48 +9,13 @@ |
|
|
|
|
#include "gc.h" |
|
|
|
|
#include "map.h" |
|
|
|
|
|
|
|
|
|
/* 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_map *map, uint32_t page) |
|
|
|
|
{ |
|
|
|
|
uint8_t data[64]; |
|
|
|
|
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(map->dev, addr, data, nbytes) < 0) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < nbytes; ++i) { |
|
|
|
|
if (data[i] != 0xff) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
addr += nbytes; |
|
|
|
|
len -= nbytes; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 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_map *map, uint32_t 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(map, page + i)) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
return flash_is_erased(map->dev, group << map->log2_pages_per_group, |
|
|
|
|
UINT32_C(1) << map->log2_pages_per_group); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Given the current user page, this function computes the page number of the
|
|
|
|
@ -123,7 +88,7 @@ static int write_page_desc(struct ftl_map *map, |
|
|
|
|
addr = page << map->log2_page_size; |
|
|
|
|
|
|
|
|
|
/* Write the page group header. */ |
|
|
|
|
if (is_page_erased(map, page)) { |
|
|
|
|
if (flash_is_erased(map->dev, page, 1)) { |
|
|
|
|
memcpy(&group.magic, "FTL", sizeof group.magic); |
|
|
|
|
group.epoch = map->epoch; |
|
|
|
|
group.tail = map->tail; |
|
|
|
@ -323,7 +288,7 @@ static int find_head(struct ftl_map *map) |
|
|
|
|
|
|
|
|
|
if (is_aligned(map->head, log2_pages_per_block)) |
|
|
|
|
return 0; |
|
|
|
|
} while (!is_page_erased(map, map->head)); |
|
|
|
|
} while (!flash_is_erased(map->dev, map->head, 1)); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|