Changeset 608:da4a18f4f414

Show
Ignore:
Timestamp:
06/12/08 13:03:43 (7 months ago)
Author:
Maxime Petazzoni <maxime.petazzoni@…>
Branch:
default
Message:

Complete the defrag_simple() code.

Comes with fixes to the nx_fs_move_region() helper function and a new
nx_fs_dump() function that displays an index of the filesystem.

Location:
nxos/base/lib/fs
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • nxos/base/lib/fs/fs.c

    r605 r608  
    219219 */ 
    220220static fs_err_t nx_fs_move_region(U32 source, U32 dest, U32 len) { 
    221   U32 data; 
     221  U32 data[EFC_PAGE_WORDS]; 
    222222 
    223223  NX_ASSERT(source < EFC_PAGES); 
    224224  NX_ASSERT(dest < EFC_PAGES); 
    225225  NX_ASSERT(len < EFC_PAGES); 
    226   NX_ASSERT(dest - source <= len); 
     226 
     227  /* TODO: allow forward moves ? */ 
     228  NX_ASSERT(dest < source || (dest > source && dest > source + len)); 
    227229 
    228230  while (len--) { 
    229     data = FLASH_BASE_PTR[source*EFC_PAGE_WORDS]; 
    230     if (!nx__efc_write_page(&data, dest)) { 
     231    memcpy((void *) data, 
     232           (void *) &(FLASH_BASE_PTR[source*EFC_PAGE_WORDS]), 
     233           EFC_PAGE_BYTES); 
     234    if (!nx__efc_write_page(data, dest)) { 
    231235      return FS_ERR_FLASH_ERROR; 
    232236    } 
    233237 
    234     /* TODO: erase the source page ? */ 
     238    if (!nx__efc_erase_page(source, 0)) { 
     239      return FS_ERR_FLASH_ERROR; 
     240    } 
    235241 
    236242    source++; 
     
    244250 */ 
    245251static fs_err_t nx_fs_relocate_to_page(fs_file_t *file, U32 origin) { 
    246   U32 page_data[EFC_PAGE_WORDS], null_data[EFC_PAGE_WORDS] = {0}; 
    247   U32 diff, i; 
    248   size_t size; 
     252  fs_err_t err; 
     253  size_t n_pages; 
     254  U32 diff; 
    249255 
    250256  diff = origin - file->origin; 
    251257 
    252258  /* Move the file's data. */ 
    253   size = nx_fs_get_file_page_count(file->size); 
    254  
    255   /* TODO: use nx_fs_move_region? */ 
    256   for (i=file->origin; i<size; i++) { 
    257     nx__efc_read_page(i, page_data); 
    258     /* TODO: figure out if we want to erase the source page now or later. */ 
    259     if (!nx__efc_write_page(page_data, i + diff) 
    260       || !nx__efc_write_page(null_data, i)) { 
    261       return FS_ERR_FLASH_ERROR; 
    262     } 
    263   } 
    264  
     259  n_pages = nx_fs_get_file_page_count(file->size); 
     260  err = nx_fs_move_region(file->origin, origin, n_pages); 
     261  if (err != FS_ERR_NO_ERROR) { 
     262    return err; 
     263  } 
     264 
     265  /* Set the file pages pointers to their respective new values. */ 
    265266  file->origin = origin; 
    266267  file->rbuf.page += diff; 
     
    638639  fs_file_t *file; 
    639640  U32 page, end; 
    640   U32 erase[EFC_PAGE_WORDS] = {0}; 
    641641 
    642642  file = nx_fs_get_file(fd); 
     
    649649  for (page = file->origin; page < end; page++) { 
    650650    if (nx_fs_page_has_magic(page)) { 
    651       /* Erase marker. */ 
    652       if (!nx__efc_write_page(erase, page)) { 
     651      if (!nx__efc_erase_page(page, 0)) { 
    653652        return FS_ERR_FLASH_ERROR; 
    654653      } 
     
    746745    } 
    747746  } 
     747 
    748748  return FS_ERR_FILE_NOT_FOUND; 
    749749} 
    750750 
     751void nx_fs_dump(void) { 
     752  U32 i = FS_PAGE_START, origin = 0; 
     753  union U32tochar nameconv; 
     754 
     755  while (nx_fs_find_next_origin(i, &origin) == FS_ERR_NO_ERROR) { 
     756    volatile U32 *metadata = &(FLASH_BASE_PTR[origin*EFC_PAGE_WORDS]); 
     757 
     758    memcpy(nameconv.integers, 
     759           (void *)(metadata + FS_FILENAME_OFFSET), 
     760           FS_FILENAME_LENGTH); 
     761 
     762    nx_display_uint(origin); 
     763    nx_display_string(":"); 
     764    nx_display_string(nameconv.chars); 
     765    nx_display_end_line(); 
     766 
     767    i = origin + nx_fs_get_file_page_count(nx_fs_get_file_size_from_metadata(metadata)); 
     768  } 
     769 
     770  nx_display_string("--"); 
     771  nx_display_uint(i); 
     772  nx_display_string("--\n"); 
     773} 
     774 
    751775/* Defrag functions. */ 
    752776 
     777/* Simple defragmentation function: tries to concatenate data blocks at 
     778 * the beginning of the flash. 
     779 * 
     780 * To acheive this, we iterate through every "hole" in the flash (empty 
     781 * spage), and try to find a block (contiguous set of files) that best 
     782 * matches the hole. If no block smaller or equal than the hole size is 
     783 * found, pull backwards the next block to fill the hole, if block there 
     784 * is. 
     785 */ 
    753786fs_err_t nx_fs_defrag_simple(void) { 
    754787  U32 i = FS_PAGE_START; 
     
    758791 
    759792  while (i < FS_PAGE_END) { 
     793    /* Find the next hole, and its size. */ 
     794 
    760795    err = nx_fs_find_next_hole(i, &next_hole); 
    761796    if (err != FS_ERR_NO_ERROR) { 
     
    764799    } 
    765800 
    766     nx_fs_find_next_origin(next_hole, &next_file); 
     801    err = nx_fs_find_next_origin(next_hole, &next_file); 
    767802    if (err != FS_ERR_NO_ERROR) { 
    768803      /* No files found after : nothing else to do */ 
     
    772807    first_next_file = next_file; 
    773808    hole_length = next_file - next_hole; 
    774     NX_ASSERT(hole_length <= 0); 
     809 
     810    NX_ASSERT(hole_length > 0); 
    775811 
    776812    /* Search for the best block to move. */ 
    777813    do { 
    778       err = nx_fs_find_next_hole(next_file, &end_of_block); 
    779       if (err != FS_ERR_NO_ERROR) { 
     814      if (nx_fs_find_next_hole(next_file, &end_of_block) != FS_ERR_NO_ERROR) { 
    780815        /* No free space after */ 
    781816        break; 
     
    787822        best_block_origin = next_file; 
    788823      } 
    789       next_file = end_of_block; 
     824 
     825      if (block_size != hole_length && 
     826        nx_fs_find_next_origin(end_of_block, &next_file) != FS_ERR_NO_ERROR) { 
     827        break; 
     828      } 
    790829    } while (next_file < FS_PAGE_END && block_size != hole_length); 
    791830 
  • nxos/base/lib/fs/fs.h

    r590 r608  
    202202                          U32 *wasted); 
    203203 
     204/** Dumps the index of the filesystem as <page>:<filename>. 
     205 */ 
     206void nx_fs_dump(void); 
     207 
    204208/** Perform a simple defragmentation of the flash filesystem. 
    205209 *