#include "battfs.h"
+#include <cfg/debug.h>
+#include <cfg/macros.h> /* MIN, MAX */
#include <mware/byteorder.h> /* cpu_to_xx */
+
#include <string.h> /* memset */
/**
*/
if (disk->read(disk, page, disk->page_size - sizeof(BattFsPageHeader), hdr, sizeof(BattFsPageHeader))
!= sizeof(BattFsPageHeader))
+ {
+ TRACEMSG("Error: page[%d]\n", page);
return false;
+ }
/* Fix endianess */
battfs_to_cpu(hdr);
+
+ ASSERT(hdr->fill <= disk->page_size - sizeof(BattFsPageHeader));
return true;
}
/* Init disk device */
if (!disk->open(disk))
+ {
+ TRACEMSG("Open error\n");
return false;
+ }
memset(filelen_table, 0, BATTFS_MAX_FILES * sizeof(pgoff_t));
+ /* Initialize min free sequence number to max value */
+ disk->min_free = MARK_PAGE_VALID;
+ /* Initialize max free sequence number to min value */
+ disk->max_free = 0;
+
+ disk->free_bytes = 0;
+ disk->disk_size = (disk_size_t)(disk->page_size - sizeof(BattFsPageHeader)) * disk->page_count;
+
+ /* Count the number of disk page per files */
for (pgcnt_t page = 0; page < disk->page_count; page++)
{
if (!battfs_readHeader(disk, page, &hdr))
rotating_init(&cks);
rotating_update(&hdr, sizeof(BattFsPageHeader) - sizeof(rotating_t), &cks);
if (cks == hdr.fcs)
+ {
+ /* Page is valid */
filelen_table[hdr.inode]++;
+
+ /* Keep trace of free space */
+ disk->free_bytes += disk->page_size - sizeof(BattFsPageHeader) - hdr.fill;
+ }
else
{
- #warning Finish me!
+ /* Check if putting mark to MARK_PAGE_VALID makes fcs correct */
+ mark_t old_mark = hdr.mark;
+ hdr.mark = MARK_PAGE_VALID;
+ rotating_init(&cks);
+ rotating_update(&hdr, sizeof(BattFsPageHeader) - sizeof(rotating_t), &cks);
+ if (cks == hdr.fcs)
+ {
+ /*
+ * This page is a valid free page.
+ * Update min and max free page sequence numbers.
+ */
+ disk->min_free = MIN(disk->min_free, old_mark);
+ disk->max_free = MAX(disk->max_free, old_mark);
+ }
+ else
+ TRACEMSG("Page [%d] invalid, keeping as free\n", page);
+
+ /* Increase free space */
+ filelen_table[BATTFS_FREE_INODE]++;
+ disk->free_bytes += disk->page_size - sizeof(BattFsPageHeader);
}
}
+ /* Once here, we have filelen_table filled with file lengths */
+ #warning Complete me!
+
return true;
}
fcs_t fcs;
} BattFsPageHeader;
+/**
+ * Mark for valid pages.
+ * Simply set to 1 all field bits.
+ */
+#define MARK_PAGE_VALID ((1 << (CPU_BITS_PER_CHAR * sizeof(mark_t))) - 1)
+
/**
* Max number of files.
*/
#define BATTFS_MAX_FILES (1 << (CPU_BITS_PER_CHAR * sizeof(inode_t)))
+/**
+ * Special inode used to identify free pages.
+ */
+#define BATTFS_FREE_INODE (BATTFS_MAX_FILES - 1)
+
/* Ensure structure has no padding added */
STATIC_ASSERT(sizeof(BattFsPageHeader) == 12);
* Is used by the filesystem to represent
* the entire disk in memory.
*/
- pgcnt_t *page_array;
+ pgcnt_t *page_array;
+
+ mark_t min_free; ///< Lowest sequence number of free page
+ mark_t max_free; ///< Highest sequence number of free page
disk_size_t disk_size; ///< Size of the disk, in bytes (page_count * page_size).
disk_size_t free_bytes; ///< Free space on the disk.