diff options
Diffstat (limited to 'cpukit/libblock/src/flashdisk.c')
-rw-r--r-- | cpukit/libblock/src/flashdisk.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/cpukit/libblock/src/flashdisk.c b/cpukit/libblock/src/flashdisk.c index 87e9e53e97..b778ab5a19 100644 --- a/cpukit/libblock/src/flashdisk.c +++ b/cpukit/libblock/src/flashdisk.c @@ -177,6 +177,7 @@ typedef struct rtems_flashdisk mappings. */ uint32_t block_count; /**< The number of avail. blocks. */ uint32_t unavail_blocks; /**< The number of unavail blocks. */ + uint32_t starvation_threshold; /**< Erased blocks starvation threshold. */ uint32_t erased_blocks; /**< The number of erased blocks. */ rtems_fdisk_device_ctl* devices; /**< The flash devices for this @@ -280,7 +281,7 @@ rtems_fdisk_printf (const rtems_flashdisk* fd, const char *format, ...) static bool rtems_fdisk_is_erased_blocks_starvation (rtems_flashdisk* fd) { - bool starvation = fd->erased_blocks < fd->unavail_blocks; + bool starvation = fd->erased_blocks < fd->starvation_threshold; if (starvation) fd->starvations++; @@ -1260,12 +1261,18 @@ rtems_fdisk_recycle_segment (rtems_flashdisk* fd, for (spage = 0; spage < ssc->pages; spage++) { - uint32_t dst_pages; rtems_fdisk_page_desc* spd = &ssc->page_descriptors[spage]; + if (!dsc && ssc->pages_active > 0) + { + rtems_fdisk_error ("recycle: no available dst segment"); + return EIO; + } + if (rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_ACTIVE) && !rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_USED)) { + uint32_t dst_pages; rtems_fdisk_page_desc* dpd; uint32_t dpage; @@ -1351,14 +1358,7 @@ rtems_fdisk_recycle_segment (rtems_flashdisk* fd, */ dst_pages = rtems_fdisk_seg_pages_available (dsc); if (dst_pages == 0) - { dsc = rtems_fdisk_seg_most_available (&fd->available); - if (!dsc) - { - rtems_fdisk_error ("recycle: no available dst segment"); - return EIO; - } - } (*pages)--; } @@ -1405,6 +1405,10 @@ rtems_fdisk_compact (rtems_flashdisk* fd) if (rtems_fdisk_is_erased_blocks_starvation (fd)) { +#if RTEMS_FDISK_TRACE + rtems_fdisk_printf (fd, " resolve starvation"); +#endif + ssc = rtems_fdisk_segment_queue_pop_head (&fd->used); if (!ssc) ssc = rtems_fdisk_segment_queue_pop_head (&fd->available); @@ -1482,7 +1486,12 @@ rtems_fdisk_compact (rtems_flashdisk* fd) */ if (!ssc || (pages == 0) || ((compacted_segs + segments) == 1)) + { +#if RTEMS_FDISK_TRACE + rtems_fdisk_printf (fd, " nothing to compact"); +#endif break; + } #if RTEMS_FDISK_TRACE rtems_fdisk_printf (fd, " ssc scan: %d-%d: p=%ld, seg=%ld", @@ -1539,6 +1548,7 @@ rtems_fdisk_recover_block_mappings (rtems_flashdisk* fd) * Scan each segment or each device recovering the valid pages. */ fd->erased_blocks = 0; + fd->starvation_threshold = 0; for (device = 0; device < fd->device_count; device++) { uint32_t segment; @@ -1557,6 +1567,8 @@ rtems_fdisk_recover_block_mappings (rtems_flashdisk* fd) sc->pages_desc = rtems_fdisk_page_desc_pages (sd, fd->block_size); sc->pages = rtems_fdisk_pages_in_segment (sd, fd->block_size) - sc->pages_desc; + if (sc->pages > fd->starvation_threshold) + fd->starvation_threshold = sc->pages; sc->pages_active = 0; sc->pages_used = 0; @@ -2225,6 +2237,7 @@ rtems_fdisk_print_status (rtems_flashdisk* fd) rtems_fdisk_printf (fd, "Block count\t%d", fd->block_count); rtems_fdisk_printf (fd, "Unavail blocks\t%d", fd->unavail_blocks); + rtems_fdisk_printf (fd, "Starvation threshold\t%d", fd->starvation_threshold); rtems_fdisk_printf (fd, "Starvations\t%d", fd->starvations); count = rtems_fdisk_segment_count_queue (&fd->available); total = count; |