Improved the performance of the garbage collector and the algorithm for
finding contiguous pages. Adjusted the file header and added a validity indicator. Removed some redundant code and fixes minor issues in the text.
This commit is contained in:
parent
deefb97c16
commit
c36a0a33fc
1 changed files with 30 additions and 29 deletions
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Coffee: A flash file system on memory-contrained sensor systems.
|
* Coffee: A flash file system for memory-contrained sensor systems.
|
||||||
* \author
|
* \author
|
||||||
* Nicolas Tsiftes <nvt@sics.se>
|
* Nicolas Tsiftes <nvt@sics.se>
|
||||||
*/
|
*/
|
||||||
|
@ -64,10 +64,11 @@
|
||||||
#define COFFEE_PAGE_COUNT (COFFEE_SIZE / COFFEE_PAGE_SIZE)
|
#define COFFEE_PAGE_COUNT (COFFEE_SIZE / COFFEE_PAGE_SIZE)
|
||||||
#define COFFEE_PAGES_PER_SECTOR (COFFEE_SECTOR_SIZE / COFFEE_PAGE_SIZE)
|
#define COFFEE_PAGES_PER_SECTOR (COFFEE_SECTOR_SIZE / COFFEE_PAGE_SIZE)
|
||||||
|
|
||||||
#define COFFEE_FLAG_ALLOCATED 0x1
|
#define COFFEE_FLAG_VALID 0x1
|
||||||
#define COFFEE_FLAG_OBSOLETE 0x2
|
#define COFFEE_FLAG_ALLOCATED 0x2
|
||||||
#define COFFEE_FLAG_MODIFIED 0x4
|
#define COFFEE_FLAG_OBSOLETE 0x4
|
||||||
#define COFFEE_FLAG_LOG 0x8
|
#define COFFEE_FLAG_MODIFIED 0x8
|
||||||
|
#define COFFEE_FLAG_LOG 0x10
|
||||||
|
|
||||||
#define LOG_CMD_MAGIC 0x7a
|
#define LOG_CMD_MAGIC 0x7a
|
||||||
|
|
||||||
|
@ -95,9 +96,9 @@ struct file_desc {
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t end;
|
uint32_t end;
|
||||||
uint16_t file_page;
|
uint16_t file_page;
|
||||||
uint8_t flags;
|
|
||||||
uint16_t max_pages;
|
uint16_t max_pages;
|
||||||
uint16_t next_log_entry;
|
uint16_t next_log_entry;
|
||||||
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dir_cache {
|
struct dir_cache {
|
||||||
|
@ -106,12 +107,12 @@ struct dir_cache {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct file_header {
|
struct file_header {
|
||||||
unsigned flags:4;
|
uint16_t log_page;
|
||||||
unsigned max_pages:12;
|
uint16_t log_entries;
|
||||||
unsigned log_page:16;
|
uint16_t log_entry_size;
|
||||||
unsigned eof_locator:16;
|
uint16_t max_pages;
|
||||||
unsigned log_entries:16;
|
uint8_t eof_hint;
|
||||||
unsigned log_entry_size:16;
|
uint8_t flags;
|
||||||
char name[COFFEE_NAME_LENGTH];
|
char name[COFFEE_NAME_LENGTH];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ get_sector_status(uint16_t sector, uint16_t *active,
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t end;
|
uint32_t end;
|
||||||
struct file_header hdr;
|
struct file_header hdr;
|
||||||
static uint16_t skip_pages;
|
static int16_t skip_pages;
|
||||||
static int last_pages_are_active;
|
static int last_pages_are_active;
|
||||||
|
|
||||||
*active = *free = *obsolete = 0;
|
*active = *free = *obsolete = 0;
|
||||||
|
@ -164,25 +165,25 @@ get_sector_status(uint16_t sector, uint16_t *active,
|
||||||
while(offset < end) {
|
while(offset < end) {
|
||||||
COFFEE_READ(&hdr, sizeof (hdr), offset);
|
COFFEE_READ(&hdr, sizeof (hdr), offset);
|
||||||
if(COFFEE_PAGE_ACTIVE(hdr)) {
|
if(COFFEE_PAGE_ACTIVE(hdr)) {
|
||||||
offset += hdr.max_pages * COFFEE_PAGE_SIZE;
|
|
||||||
last_pages_are_active = 1;
|
last_pages_are_active = 1;
|
||||||
|
offset += hdr.max_pages * COFFEE_PAGE_SIZE;
|
||||||
*active += hdr.max_pages;
|
*active += hdr.max_pages;
|
||||||
} else if(COFFEE_PAGE_OBSOLETE(hdr)) {
|
} else if(COFFEE_PAGE_OBSOLETE(hdr)) {
|
||||||
last_pages_are_active = 0;
|
last_pages_are_active = 0;
|
||||||
offset += hdr.max_pages * COFFEE_PAGE_SIZE;
|
offset += hdr.max_pages * COFFEE_PAGE_SIZE;
|
||||||
*obsolete += hdr.max_pages;
|
*obsolete += hdr.max_pages;
|
||||||
} else if(COFFEE_PAGE_FREE(hdr)) {
|
} else if(COFFEE_PAGE_FREE(hdr)) {
|
||||||
++*free;
|
*free = (end - offset) / COFFEE_PAGE_SIZE;
|
||||||
offset += COFFEE_PAGE_SIZE;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_pages = *active + *free + *obsolete - COFFEE_PAGES_PER_SECTOR;
|
skip_pages = *active + *obsolete - COFFEE_PAGES_PER_SECTOR;
|
||||||
if(skip_pages > 0) {
|
if(skip_pages > 0) {
|
||||||
if(last_pages_are_active) {
|
if(last_pages_are_active) {
|
||||||
*active = COFFEE_PAGES_PER_SECTOR - *free - *obsolete;
|
*active = COFFEE_PAGES_PER_SECTOR - *obsolete;
|
||||||
} else {
|
} else {
|
||||||
*obsolete = COFFEE_PAGES_PER_SECTOR - *free - *active;
|
*obsolete = COFFEE_PAGES_PER_SECTOR - *active;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,8 +259,8 @@ find_file(const char *name)
|
||||||
page += hdr.max_pages;
|
page += hdr.max_pages;
|
||||||
} else {
|
} else {
|
||||||
/* It follows from the properties of the page allocation algorithm
|
/* It follows from the properties of the page allocation algorithm
|
||||||
that if a free page is encountered, the rest of the sector is
|
that if a free page is encountered, then the rest of the sector
|
||||||
also free. */
|
is also free. */
|
||||||
page = (page + COFFEE_PAGES_PER_SECTOR) & ~(COFFEE_PAGES_PER_SECTOR - 1);
|
page = (page + COFFEE_PAGES_PER_SECTOR) & ~(COFFEE_PAGES_PER_SECTOR - 1);
|
||||||
}
|
}
|
||||||
watchdog_periodic();
|
watchdog_periodic();
|
||||||
|
@ -278,14 +279,14 @@ find_offset_in_file(int first_page)
|
||||||
|
|
||||||
READ_HEADER(&hdr, first_page);
|
READ_HEADER(&hdr, first_page);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move from the end of the file towards the beginning and look for
|
* Move from the end of the file towards the beginning and look for
|
||||||
* a byte that has been modified.
|
* a byte that has been modified.
|
||||||
*
|
*
|
||||||
* One important implication of this is that if the last written bytes
|
* An important implication of this is that if the last written bytes
|
||||||
* are zeroes, then these are skipped from the calculation.
|
* are zeroes, then these are skipped from the calculation.
|
||||||
*
|
*/
|
||||||
*/
|
|
||||||
for(page = first_page + hdr.max_pages - 1; page >= first_page; page--) {
|
for(page = first_page + hdr.max_pages - 1; page >= first_page; page--) {
|
||||||
watchdog_periodic();
|
watchdog_periodic();
|
||||||
COFFEE_READ(buf, sizeof (buf), page * COFFEE_PAGE_SIZE);
|
COFFEE_READ(buf, sizeof (buf), page * COFFEE_PAGE_SIZE);
|
||||||
|
@ -321,7 +322,7 @@ find_contiguous_pages(unsigned wanted)
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
page++;
|
page = (page + COFFEE_PAGES_PER_SECTOR) & ~(COFFEE_PAGES_PER_SECTOR - 1);
|
||||||
} else {
|
} else {
|
||||||
start = -1;
|
start = -1;
|
||||||
page += hdr.max_pages;
|
page += hdr.max_pages;
|
||||||
|
@ -955,13 +956,13 @@ cfs_coffee_reserve(const char *name, uint32_t size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(hdr.name, name, sizeof (hdr.name));
|
memcpy(hdr.name, name, sizeof (hdr.name));
|
||||||
hdr.name[sizeof (hdr.name) - 1] = '\0';
|
hdr.name[sizeof (hdr.name) - 1] = '\0';
|
||||||
hdr.max_pages = need_pages;
|
hdr.max_pages = need_pages;
|
||||||
hdr.flags = COFFEE_FLAG_ALLOCATED;
|
hdr.flags = COFFEE_FLAG_ALLOCATED | COFFEE_FLAG_VALID;
|
||||||
hdr.log_page = 0;
|
hdr.log_page = 0;
|
||||||
hdr.eof_locator = 0;
|
hdr.eof_hint = 0;
|
||||||
hdr.log_entries = 0;
|
hdr.log_entries = 0;
|
||||||
hdr.log_entry_size = 0;
|
hdr.log_entry_size = 0;
|
||||||
WRITE_HEADER(&hdr, page);
|
WRITE_HEADER(&hdr, page);
|
||||||
|
|
Loading…
Reference in a new issue