Merge pull request #1724 from nvt/coffee-simplify
Coffee: minor enhancements
This commit is contained in:
commit
a8989f9f1c
|
@ -75,12 +75,6 @@
|
||||||
#error "Cannot have COFFEE_APPEND_ONLY set when COFFEE_MICRO_LOGS is set."
|
#error "Cannot have COFFEE_APPEND_ONLY set when COFFEE_MICRO_LOGS is set."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* I/O semantics can be set on file descriptors in order to optimize
|
|
||||||
file access on certain storage types. */
|
|
||||||
#ifndef COFFEE_IO_SEMANTICS
|
|
||||||
#define COFFEE_IO_SEMANTICS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent sectors from being erased directly after file removal.
|
* Prevent sectors from being erased directly after file removal.
|
||||||
* This will level the wear across sectors better, but may lead
|
* This will level the wear across sectors better, but may lead
|
||||||
|
@ -94,16 +88,21 @@
|
||||||
#error COFFEE_START must point to the first byte in a sector.
|
#error COFFEE_START must point to the first byte in a sector.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* File descriptor flags. */
|
||||||
#define COFFEE_FD_FREE 0x0
|
#define COFFEE_FD_FREE 0x0
|
||||||
#define COFFEE_FD_READ 0x1
|
#define COFFEE_FD_READ 0x1
|
||||||
#define COFFEE_FD_WRITE 0x2
|
#define COFFEE_FD_WRITE 0x2
|
||||||
#define COFFEE_FD_APPEND 0x4
|
#define COFFEE_FD_APPEND 0x4
|
||||||
|
|
||||||
|
/* File object flags. */
|
||||||
#define COFFEE_FILE_MODIFIED 0x1
|
#define COFFEE_FILE_MODIFIED 0x1
|
||||||
|
|
||||||
|
/* Internal Coffee markers. */
|
||||||
#define INVALID_PAGE ((coffee_page_t)-1)
|
#define INVALID_PAGE ((coffee_page_t)-1)
|
||||||
#define UNKNOWN_OFFSET ((cfs_offset_t)-1)
|
#define UNKNOWN_OFFSET ((cfs_offset_t)-1)
|
||||||
|
|
||||||
|
/* File removal actions. They can have the same values because
|
||||||
|
they are passed as separate parameters. */
|
||||||
#define REMOVE_LOG 1
|
#define REMOVE_LOG 1
|
||||||
#define CLOSE_FDS 1
|
#define CLOSE_FDS 1
|
||||||
#define ALLOW_GC 1
|
#define ALLOW_GC 1
|
||||||
|
@ -176,9 +175,7 @@ struct file_desc {
|
||||||
cfs_offset_t offset;
|
cfs_offset_t offset;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
#if COFFEE_IO_SEMANTICS
|
|
||||||
uint8_t io_flags;
|
uint8_t io_flags;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The file header structure mimics the representation of file headers
|
/* The file header structure mimics the representation of file headers
|
||||||
|
@ -221,11 +218,9 @@ static void
|
||||||
read_header(struct file_header *hdr, coffee_page_t page)
|
read_header(struct file_header *hdr, coffee_page_t page)
|
||||||
{
|
{
|
||||||
COFFEE_READ(hdr, sizeof(*hdr), page * COFFEE_PAGE_SIZE);
|
COFFEE_READ(hdr, sizeof(*hdr), page * COFFEE_PAGE_SIZE);
|
||||||
#if DEBUG
|
if(DEBUG && HDR_ACTIVE(*hdr) && !HDR_VALID(*hdr)) {
|
||||||
if(HDR_ACTIVE(*hdr) && !HDR_VALID(*hdr)) {
|
PRINTF("Coffee: Invalid header at page %u!\n", (unsigned)page);
|
||||||
PRINTF("Invalid header at page %u!\n", (unsigned)page);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static cfs_offset_t
|
static cfs_offset_t
|
||||||
|
@ -450,10 +445,7 @@ load_file(coffee_page_t start, struct file_header *hdr)
|
||||||
file->page = start;
|
file->page = start;
|
||||||
file->end = UNKNOWN_OFFSET;
|
file->end = UNKNOWN_OFFSET;
|
||||||
file->max_pages = hdr->max_pages;
|
file->max_pages = hdr->max_pages;
|
||||||
file->flags = 0;
|
file->flags = HDR_MODIFIED(*hdr) ? COFFEE_FILE_MODIFIED : 0;
|
||||||
if(HDR_MODIFIED(*hdr)) {
|
|
||||||
file->flags |= COFFEE_FILE_MODIFIED;
|
|
||||||
}
|
|
||||||
/* We don't know the amount of records yet. */
|
/* We don't know the amount of records yet. */
|
||||||
file->record_count = -1;
|
file->record_count = -1;
|
||||||
|
|
||||||
|
@ -561,8 +553,8 @@ find_contiguous_pages(coffee_page_t amount)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
remove_by_page(coffee_page_t page, int remove_log, int close_fds,
|
remove_by_page(coffee_page_t page, int remove_log,
|
||||||
int gc_allowed)
|
int close_fds, int gc_allowed)
|
||||||
{
|
{
|
||||||
struct file_header hdr;
|
struct file_header hdr;
|
||||||
int i;
|
int i;
|
||||||
|
@ -600,11 +592,9 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !COFFEE_EXTENDED_WEAR_LEVELLING
|
if(!COFFEE_EXTENDED_WEAR_LEVELLING && gc_allowed) {
|
||||||
if(gc_allowed) {
|
|
||||||
collect_garbage(GC_RELUCTANT);
|
collect_garbage(GC_RELUCTANT);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -997,6 +987,7 @@ cfs_open(const char *name, int flags)
|
||||||
|
|
||||||
fdp = &coffee_fd_set[fd];
|
fdp = &coffee_fd_set[fd];
|
||||||
fdp->flags = 0;
|
fdp->flags = 0;
|
||||||
|
fdp->io_flags = 0;
|
||||||
|
|
||||||
fdp->file = find_file(name);
|
fdp->file = find_file(name);
|
||||||
if(fdp->file == NULL) {
|
if(fdp->file == NULL) {
|
||||||
|
@ -1104,19 +1095,13 @@ cfs_read(int fd, void *buf, unsigned size)
|
||||||
fdp = &coffee_fd_set[fd];
|
fdp = &coffee_fd_set[fd];
|
||||||
file = fdp->file;
|
file = fdp->file;
|
||||||
|
|
||||||
#if COFFEE_IO_SEMANTICS
|
|
||||||
if(fdp->io_flags & CFS_COFFEE_IO_ENSURE_READ_LENGTH) {
|
if(fdp->io_flags & CFS_COFFEE_IO_ENSURE_READ_LENGTH) {
|
||||||
while(fdp->offset + size > file->end) {
|
while(fdp->offset + size > file->end) {
|
||||||
((char*)buf)[--size] = 0;
|
((char *)buf)[--size] = '\0';
|
||||||
}
|
}
|
||||||
} else {
|
} else if(fdp->offset + size > file->end) {
|
||||||
#endif
|
|
||||||
if(fdp->offset + size > file->end) {
|
|
||||||
size = file->end - fdp->offset;
|
size = file->end - fdp->offset;
|
||||||
}
|
}
|
||||||
#if COFFEE_IO_SEMANTICS
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If the file is not modified, read directly from the file extent. */
|
/* If the file is not modified, read directly from the file extent. */
|
||||||
if(!FILE_MODIFIED(file)) {
|
if(!FILE_MODIFIED(file)) {
|
||||||
|
@ -1173,9 +1158,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
file = fdp->file;
|
file = fdp->file;
|
||||||
|
|
||||||
/* Attempt to extend the file if we try to write past the end. */
|
/* Attempt to extend the file if we try to write past the end. */
|
||||||
#if COFFEE_IO_SEMANTICS
|
|
||||||
if(!(fdp->io_flags & CFS_COFFEE_IO_FIRM_SIZE)) {
|
if(!(fdp->io_flags & CFS_COFFEE_IO_FIRM_SIZE)) {
|
||||||
#endif
|
|
||||||
while(size + fdp->offset + sizeof(struct file_header) >
|
while(size + fdp->offset + sizeof(struct file_header) >
|
||||||
(file->max_pages * COFFEE_PAGE_SIZE)) {
|
(file->max_pages * COFFEE_PAGE_SIZE)) {
|
||||||
if(merge_log(file->page, 1) < 0) {
|
if(merge_log(file->page, 1) < 0) {
|
||||||
|
@ -1184,17 +1167,11 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
file = fdp->file;
|
file = fdp->file;
|
||||||
PRINTF("Extended the file at page %u\n", (unsigned)file->page);
|
PRINTF("Extended the file at page %u\n", (unsigned)file->page);
|
||||||
}
|
}
|
||||||
#if COFFEE_IO_SEMANTICS
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if COFFEE_MICRO_LOGS
|
#if COFFEE_MICRO_LOGS
|
||||||
#if COFFEE_IO_SEMANTICS
|
|
||||||
if(!(fdp->io_flags & CFS_COFFEE_IO_FLASH_AWARE) &&
|
if(!(fdp->io_flags & CFS_COFFEE_IO_FLASH_AWARE) &&
|
||||||
(FILE_MODIFIED(file) || fdp->offset < file->end)) {
|
(FILE_MODIFIED(file) || fdp->offset < file->end)) {
|
||||||
#else
|
|
||||||
if(FILE_MODIFIED(file) || fdp->offset < file->end) {
|
|
||||||
#endif
|
|
||||||
need_dummy_write = 0;
|
need_dummy_write = 0;
|
||||||
for(bytes_left = size; bytes_left > 0;) {
|
for(bytes_left = size; bytes_left > 0;) {
|
||||||
lp.offset = fdp->offset;
|
lp.offset = fdp->offset;
|
||||||
|
@ -1236,16 +1213,14 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif /* COFFEE_MICRO_LOGS */
|
#endif /* COFFEE_MICRO_LOGS */
|
||||||
#if COFFEE_APPEND_ONLY
|
if(COFFEE_APPEND_ONLY && fdp->offset < file->end) {
|
||||||
if(fdp->offset < file->end) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* COFFEE_APPEND_ONLY */
|
|
||||||
|
|
||||||
COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset));
|
COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset));
|
||||||
fdp->offset += size;
|
fdp->offset += size;
|
||||||
#if COFFEE_MICRO_LOGS
|
#if COFFEE_MICRO_LOGS
|
||||||
}
|
}
|
||||||
#endif /* COFFEE_MICRO_LOGS */
|
#endif /* COFFEE_MICRO_LOGS */
|
||||||
|
|
||||||
if(fdp->offset > file->end) {
|
if(fdp->offset > file->end) {
|
||||||
|
@ -1262,7 +1237,7 @@ cfs_opendir(struct cfs_dir *dir, const char *name)
|
||||||
* Coffee is only guaranteed to support the directory names "/" and ".",
|
* Coffee is only guaranteed to support the directory names "/" and ".",
|
||||||
* but it does not enforce this currently.
|
* but it does not enforce this currently.
|
||||||
*/
|
*/
|
||||||
memset(dir->dummy_space, 0, sizeof(coffee_page_t));
|
memset(dir->state, 0, sizeof(coffee_page_t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -1273,7 +1248,7 @@ cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record)
|
||||||
coffee_page_t page;
|
coffee_page_t page;
|
||||||
coffee_page_t next_page;
|
coffee_page_t next_page;
|
||||||
|
|
||||||
memcpy(&page, dir->dummy_space, sizeof(coffee_page_t));
|
memcpy(&page, dir->state, sizeof(coffee_page_t));
|
||||||
|
|
||||||
while(page < COFFEE_PAGE_COUNT) {
|
while(page < COFFEE_PAGE_COUNT) {
|
||||||
read_header(&hdr, page);
|
read_header(&hdr, page);
|
||||||
|
@ -1283,7 +1258,7 @@ cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record)
|
||||||
record->size = file_end(page);
|
record->size = file_end(page);
|
||||||
|
|
||||||
next_page = next_file(page, &hdr);
|
next_page = next_file(page, &hdr);
|
||||||
memcpy(dir->dummy_space, &next_page, sizeof(coffee_page_t));
|
memcpy(dir->state, &next_page, sizeof(coffee_page_t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
page = next_file(page, &hdr);
|
page = next_file(page, &hdr);
|
||||||
|
|
|
@ -68,7 +68,9 @@ typedef CFS_CONF_OFFSET_TYPE cfs_offset_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct cfs_dir {
|
struct cfs_dir {
|
||||||
char dummy_space[32];
|
/* Iteration state, which is implementation-defined and should not be
|
||||||
|
accessed externally. */
|
||||||
|
char state[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cfs_dirent {
|
struct cfs_dirent {
|
||||||
|
|
|
@ -55,7 +55,6 @@
|
||||||
#define COFFEE_LOG_SIZE 8192
|
#define COFFEE_LOG_SIZE 8192
|
||||||
#define COFFEE_LOG_TABLE_LIMIT 256
|
#define COFFEE_LOG_TABLE_LIMIT 256
|
||||||
#define COFFEE_MICRO_LOGS 0
|
#define COFFEE_MICRO_LOGS 0
|
||||||
#define COFFEE_IO_SEMANTICS 1
|
|
||||||
|
|
||||||
#define COFFEE_WRITE(buf, size, offset) \
|
#define COFFEE_WRITE(buf, size, offset) \
|
||||||
xmem_pwrite((char *)(buf), (size), COFFEE_START + (offset))
|
xmem_pwrite((char *)(buf), (size), COFFEE_START + (offset))
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
#endif
|
#endif
|
||||||
#define COFFEE_LOG_SIZE 1024
|
#define COFFEE_LOG_SIZE 1024
|
||||||
|
|
||||||
#define COFFEE_IO_SEMANTICS 1
|
|
||||||
#define COFFEE_APPEND_ONLY 0
|
#define COFFEE_APPEND_ONLY 0
|
||||||
#define COFFEE_MICRO_LOGS 1
|
#define COFFEE_MICRO_LOGS 1
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue