Merge pull request #1724 from nvt/coffee-simplify

Coffee: minor enhancements
This commit is contained in:
Nicolas Tsiftes 2016-06-15 18:56:10 +02:00 committed by GitHub
commit a8989f9f1c
4 changed files with 40 additions and 65 deletions

View file

@ -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,24 +88,29 @@
#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
#define INVALID_PAGE ((coffee_page_t)-1) /* Internal Coffee markers. */
#define INVALID_PAGE ((coffee_page_t)-1)
#define UNKNOWN_OFFSET ((cfs_offset_t)-1) #define UNKNOWN_OFFSET ((cfs_offset_t)-1)
#define REMOVE_LOG 1 /* File removal actions. They can have the same values because
#define CLOSE_FDS 1 they are passed as separate parameters. */
#define ALLOW_GC 1 #define REMOVE_LOG 1
#define CLOSE_FDS 1
#define ALLOW_GC 1
/* "Greedy" garbage collection erases as many sectors as possible. */ /* "Greedy" garbage collection erases as many sectors as possible. */
#define GC_GREEDY 0 #define GC_GREEDY 0
/* "Reluctant" garbage collection stops after erasing one sector. */ /* "Reluctant" garbage collection stops after erasing one sector. */
#define GC_RELUCTANT 1 #define GC_RELUCTANT 1
/* File descriptor macros. */ /* File descriptor macros. */
#define FD_VALID(fd) ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \ #define FD_VALID(fd) ((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \
@ -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 size = file->end - fdp->offset;
if(fdp->offset + size > file->end) {
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,28 +1158,20 @@ 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) { return -1;
return -1; }
file = fdp->file;
PRINTF("Extended the file at page %u\n", (unsigned)file->page);
} }
file = fdp->file;
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);

View file

@ -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 {

View file

@ -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))

View file

@ -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