reduced the code size by 200 bytes.
fixed an EOF hint bug that occured when files where extended.
This commit is contained in:
parent
a50d5b701e
commit
532ebc1e9a
1 changed files with 59 additions and 50 deletions
|
@ -68,6 +68,8 @@
|
||||||
#define COFFEE_FD_APPEND 0x4
|
#define COFFEE_FD_APPEND 0x4
|
||||||
#define COFFEE_FD_MODIFIED 0x8
|
#define COFFEE_FD_MODIFIED 0x8
|
||||||
|
|
||||||
|
#define INVALID_PAGE ((coffee_page_t)-1)
|
||||||
|
|
||||||
#define FD_VALID(fd) \
|
#define FD_VALID(fd) \
|
||||||
((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \
|
((fd) >= 0 && (fd) < COFFEE_FD_SET_SIZE && \
|
||||||
coffee_fd_set[(fd)].flags != COFFEE_FD_FREE)
|
coffee_fd_set[(fd)].flags != COFFEE_FD_FREE)
|
||||||
|
@ -128,10 +130,6 @@ struct log_param {
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ABS_OFFSET(file_page, file_offset) \
|
|
||||||
((file_page) * COFFEE_PAGE_SIZE + \
|
|
||||||
sizeof(struct file_header) + (file_offset))
|
|
||||||
|
|
||||||
static struct dir_cache dir_cache[COFFEE_DIR_CACHE_ENTRIES];
|
static struct dir_cache dir_cache[COFFEE_DIR_CACHE_ENTRIES];
|
||||||
static struct file_desc coffee_fd_set[COFFEE_FD_SET_SIZE];
|
static struct file_desc coffee_fd_set[COFFEE_FD_SET_SIZE];
|
||||||
|
|
||||||
|
@ -148,6 +146,12 @@ 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);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static coffee_offset_t
|
||||||
|
absolute_offset(coffee_page_t page, coffee_offset_t offset)
|
||||||
|
{
|
||||||
|
return page * COFFEE_PAGE_SIZE + sizeof(struct file_header) + offset;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
get_sector_status(uint16_t sector, coffee_page_t *active,
|
get_sector_status(uint16_t sector, coffee_page_t *active,
|
||||||
coffee_page_t *free, coffee_page_t *obsolete) {
|
coffee_page_t *free, coffee_page_t *obsolete) {
|
||||||
|
@ -193,7 +197,7 @@ get_sector_status(uint16_t sector, coffee_page_t *active,
|
||||||
(unsigned)skip_pages, (int)sector);
|
(unsigned)skip_pages, (int)sector);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = sector_start + skip_pages * COFFEE_PAGE_SIZE;
|
offset = sector_start + (skip_pages * COFFEE_PAGE_SIZE);
|
||||||
end = (sector + 1) * COFFEE_SECTOR_SIZE;
|
end = (sector + 1) * COFFEE_SECTOR_SIZE;
|
||||||
jump = 0;
|
jump = 0;
|
||||||
|
|
||||||
|
@ -340,10 +344,10 @@ find_offset_in_file(int first_page)
|
||||||
{
|
{
|
||||||
struct file_header hdr;
|
struct file_header hdr;
|
||||||
unsigned char buf[COFFEE_PAGE_SIZE];
|
unsigned char buf[COFFEE_PAGE_SIZE];
|
||||||
int page;
|
coffee_page_t page;
|
||||||
int i;
|
int i;
|
||||||
int search_limit;
|
int search_limit;
|
||||||
coffee_offset_t range_start, range_end, part_size;
|
coffee_page_t range_start, range_end, part_size;
|
||||||
|
|
||||||
read_header(&hdr, first_page);
|
read_header(&hdr, first_page);
|
||||||
search_limit = 0;
|
search_limit = 0;
|
||||||
|
@ -375,11 +379,10 @@ find_offset_in_file(int first_page)
|
||||||
COFFEE_READ(buf, sizeof(buf), page * COFFEE_PAGE_SIZE);
|
COFFEE_READ(buf, sizeof(buf), page * COFFEE_PAGE_SIZE);
|
||||||
for(i = COFFEE_PAGE_SIZE - 1; i >= 0; i--) {
|
for(i = COFFEE_PAGE_SIZE - 1; i >= 0; i--) {
|
||||||
if(buf[i] != 0) {
|
if(buf[i] != 0) {
|
||||||
if(page == first_page) {
|
if(page == first_page && i < sizeof(hdr)) {
|
||||||
return i < sizeof(hdr) ? 0 : 1 + i - sizeof(hdr);
|
return 0;
|
||||||
} else {
|
|
||||||
return 1 + i + (page - first_page) * COFFEE_PAGE_SIZE - sizeof(hdr);
|
|
||||||
}
|
}
|
||||||
|
return 1 + i + ((page - first_page) * COFFEE_PAGE_SIZE) - sizeof(hdr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -388,10 +391,10 @@ find_offset_in_file(int first_page)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static coffee_page_t
|
||||||
find_contiguous_pages(unsigned wanted)
|
find_contiguous_pages(unsigned wanted)
|
||||||
{
|
{
|
||||||
int page, start;
|
coffee_page_t page, start;
|
||||||
struct file_header hdr;
|
struct file_header hdr;
|
||||||
|
|
||||||
start = -1;
|
start = -1;
|
||||||
|
@ -485,12 +488,18 @@ remove_by_page(coffee_page_t page, int remove_log, int close_fds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static coffee_page_t
|
||||||
|
page_count(coffee_offset_t size)
|
||||||
|
{
|
||||||
|
return (size + sizeof(struct file_header) + COFFEE_PAGE_SIZE - 1) /
|
||||||
|
COFFEE_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
reserve(const char *name, uint32_t size, int allow_duplicates)
|
reserve(const char *name, coffee_page_t pages, int allow_duplicates)
|
||||||
{
|
{
|
||||||
struct file_header hdr;
|
struct file_header hdr;
|
||||||
unsigned need_pages;
|
coffee_page_t page;
|
||||||
int page;
|
|
||||||
|
|
||||||
watchdog_stop();
|
watchdog_stop();
|
||||||
|
|
||||||
|
@ -499,13 +508,11 @@ reserve(const char *name, uint32_t size, int allow_duplicates)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
need_pages = (size + sizeof(hdr) + COFFEE_PAGE_SIZE - 1) / COFFEE_PAGE_SIZE;
|
page = find_contiguous_pages(pages);
|
||||||
|
if(page == INVALID_PAGE) {
|
||||||
page = find_contiguous_pages(need_pages);
|
|
||||||
if(page < 0) {
|
|
||||||
cfs_garbage_collect();
|
cfs_garbage_collect();
|
||||||
page = find_contiguous_pages(need_pages);
|
page = find_contiguous_pages(pages);
|
||||||
if(page < 0) {
|
if(page == INVALID_PAGE) {
|
||||||
watchdog_start();
|
watchdog_start();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -513,7 +520,7 @@ reserve(const char *name, uint32_t size, int allow_duplicates)
|
||||||
|
|
||||||
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 = pages;
|
||||||
hdr.flags = COFFEE_FLAG_ALLOCATED | COFFEE_FLAG_VALID;
|
hdr.flags = COFFEE_FLAG_ALLOCATED | COFFEE_FLAG_VALID;
|
||||||
hdr.log_page = 0;
|
hdr.log_page = 0;
|
||||||
hdr.eof_hint = 0;
|
hdr.eof_hint = 0;
|
||||||
|
@ -564,7 +571,7 @@ get_record_index(coffee_page_t log_page, uint16_t search_records,
|
||||||
int16_t match_index, i;
|
int16_t match_index, i;
|
||||||
uint16_t record_count;
|
uint16_t record_count;
|
||||||
|
|
||||||
base = ABS_OFFSET(log_page, sizeof(uint16_t) * search_records);
|
base = absolute_offset(log_page, sizeof(uint16_t) * search_records);
|
||||||
record_count = search_records > COFFEE_LOG_TABLE_LIMIT ?
|
record_count = search_records > COFFEE_LOG_TABLE_LIMIT ?
|
||||||
COFFEE_LOG_TABLE_LIMIT : search_records;
|
COFFEE_LOG_TABLE_LIMIT : search_records;
|
||||||
processed = 0;
|
processed = 0;
|
||||||
|
@ -656,8 +663,8 @@ create_log(coffee_page_t file_page, struct file_header *hdr)
|
||||||
size += log_records * log_record_size; /* Log data size. */
|
size += log_records * log_record_size; /* Log data size. */
|
||||||
|
|
||||||
log_page = reserve(create_log_name(log_name, sizeof(log_name), hdr->name),
|
log_page = reserve(create_log_name(log_name, sizeof(log_name), hdr->name),
|
||||||
size, 0);
|
page_count(size), 0);
|
||||||
if(log_page < 0) {
|
if(log_page == INVALID_PAGE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,10 +705,8 @@ merge_log(coffee_page_t file_page, int extend)
|
||||||
* already been calculated with in the previous reservation.
|
* already been calculated with in the previous reservation.
|
||||||
*/
|
*/
|
||||||
max_pages = hdr.max_pages * (1 << extend);
|
max_pages = hdr.max_pages * (1 << extend);
|
||||||
new_file_page = reserve(hdr.name,
|
new_file_page = reserve(hdr.name, max_pages, 1);
|
||||||
max_pages * COFFEE_PAGE_SIZE - sizeof(hdr),
|
if(new_file_page == INVALID_PAGE) {
|
||||||
1);
|
|
||||||
if(new_file_page < 0) {
|
|
||||||
cfs_close(fd);
|
cfs_close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -717,7 +722,7 @@ merge_log(coffee_page_t file_page, int extend)
|
||||||
return -1;
|
return -1;
|
||||||
} else if(n > 0) {
|
} else if(n > 0) {
|
||||||
COFFEE_WRITE(buf, n,
|
COFFEE_WRITE(buf, n,
|
||||||
ABS_OFFSET(new_file_page, offset));
|
absolute_offset(new_file_page, offset));
|
||||||
offset += n;
|
offset += n;
|
||||||
}
|
}
|
||||||
} while(n != 0);
|
} while(n != 0);
|
||||||
|
@ -732,8 +737,11 @@ merge_log(coffee_page_t file_page, int extend)
|
||||||
read_header(&hdr2, new_file_page);
|
read_header(&hdr2, new_file_page);
|
||||||
hdr2.log_record_size = hdr.log_record_size;
|
hdr2.log_record_size = hdr.log_record_size;
|
||||||
hdr2.log_records = hdr.log_records;
|
hdr2.log_records = hdr.log_records;
|
||||||
hdr2.eof_hint = hdr.eof_hint;
|
hdr2.eof_hint = extend ? 0 : hdr.eof_hint;
|
||||||
write_header(&hdr2, new_file_page);
|
write_header(&hdr2, new_file_page);
|
||||||
|
if(extend) {
|
||||||
|
update_eof_hint(new_file_page, offset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Point the file descriptors to the new file page. */
|
/* Point the file descriptors to the new file page. */
|
||||||
for(n = 0; n < COFFEE_FD_SET_SIZE; n++) {
|
for(n = 0; n < COFFEE_FD_SET_SIZE; n++) {
|
||||||
|
@ -771,7 +779,7 @@ find_next_record(struct file_desc *fdp, coffee_page_t log_page,
|
||||||
preferred_batch_size : log_records - processed;
|
preferred_batch_size : log_records - processed;
|
||||||
|
|
||||||
COFFEE_READ(&indices, batch_size * sizeof(indices[0]),
|
COFFEE_READ(&indices, batch_size * sizeof(indices[0]),
|
||||||
ABS_OFFSET(log_page, processed * sizeof(indices[0])));
|
absolute_offset(log_page, processed * sizeof(indices[0])));
|
||||||
for(i = 0; i < batch_size && indices[i] != 0; i++);
|
for(i = 0; i < batch_size && indices[i] != 0; i++);
|
||||||
log_record = i;
|
log_record = i;
|
||||||
|
|
||||||
|
@ -818,7 +826,7 @@ write_log_page(struct file_desc *fdp, struct log_param *lp)
|
||||||
} else {
|
} else {
|
||||||
/* Create a log structure. */
|
/* Create a log structure. */
|
||||||
log_page = create_log(fdp->file_page, &hdr);
|
log_page = create_log(fdp->file_page, &hdr);
|
||||||
if(log_page < 0) {
|
if(log_page == INVALID_PAGE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
PRINTF("Coffee: Created a log structure for file %s at page %u\n",
|
PRINTF("Coffee: Created a log structure for file %s at page %u\n",
|
||||||
|
@ -837,7 +845,7 @@ write_log_page(struct file_desc *fdp, struct log_param *lp)
|
||||||
if((lp->offset > 0 || lp->size != log_record_size) &&
|
if((lp->offset > 0 || lp->size != log_record_size) &&
|
||||||
read_log_page(&hdr, fdp->next_log_record - 1, &lp_out) < 0) {
|
read_log_page(&hdr, fdp->next_log_record - 1, &lp_out) < 0) {
|
||||||
COFFEE_READ(copy_buf, sizeof(copy_buf),
|
COFFEE_READ(copy_buf, sizeof(copy_buf),
|
||||||
ABS_OFFSET(fdp->file_page, region * log_record_size));
|
absolute_offset(fdp->file_page, region * log_record_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy((char *) ©_buf + lp->offset, lp->buf, lp->size);
|
memcpy((char *) ©_buf + lp->offset, lp->buf, lp->size);
|
||||||
|
@ -850,7 +858,7 @@ write_log_page(struct file_desc *fdp, struct log_param *lp)
|
||||||
COFFEE_WRITE(copy_buf, sizeof(copy_buf), base);
|
COFFEE_WRITE(copy_buf, sizeof(copy_buf), base);
|
||||||
++region;
|
++region;
|
||||||
COFFEE_WRITE(®ion, sizeof(region),
|
COFFEE_WRITE(®ion, sizeof(region),
|
||||||
ABS_OFFSET(log_page, log_record * sizeof(region)));
|
absolute_offset(log_page, log_record * sizeof(region)));
|
||||||
fdp->next_log_record = log_record + 1;
|
fdp->next_log_record = log_record + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,15 +894,14 @@ cfs_open(const char *name, int flags)
|
||||||
fdp = &coffee_fd_set[fd];
|
fdp = &coffee_fd_set[fd];
|
||||||
|
|
||||||
page = find_file(name);
|
page = find_file(name);
|
||||||
if(page < 0) {
|
if(page == INVALID_PAGE) {
|
||||||
if((flags & (CFS_READ | CFS_WRITE)) == CFS_READ) {
|
if((flags & (CFS_READ | CFS_WRITE)) == CFS_READ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if((page = reserve(name, COFFEE_DYN_SIZE, 1)) < 0) {
|
if((page = reserve(name, page_count(COFFEE_DYN_SIZE), 1)) == INVALID_PAGE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fdp->max_pages = (COFFEE_DYN_SIZE + sizeof(hdr) +
|
fdp->max_pages = page_count(COFFEE_DYN_SIZE);
|
||||||
COFFEE_PAGE_SIZE - 1) / COFFEE_PAGE_SIZE;
|
|
||||||
} else {
|
} else {
|
||||||
read_header(&hdr, page);
|
read_header(&hdr, page);
|
||||||
if(COFFEE_FILE_MODIFIED(hdr)) {
|
if(COFFEE_FILE_MODIFIED(hdr)) {
|
||||||
|
@ -925,11 +932,13 @@ unsigned
|
||||||
cfs_seek(int fd, unsigned offset)
|
cfs_seek(int fd, unsigned offset)
|
||||||
{
|
{
|
||||||
struct file_header hdr;
|
struct file_header hdr;
|
||||||
|
struct file_desc *fdp;
|
||||||
|
|
||||||
if(!FD_VALID(fd)) {
|
if(!FD_VALID(fd)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
read_header(&hdr, coffee_fd_set[fd].file_page);
|
fdp = &coffee_fd_set[fd];
|
||||||
|
read_header(&hdr, fdp->file_page);
|
||||||
|
|
||||||
/* Check if the offset is within the file boundary. */
|
/* Check if the offset is within the file boundary. */
|
||||||
if(sizeof(hdr) + offset >= hdr.max_pages * COFFEE_PAGE_SIZE ||
|
if(sizeof(hdr) + offset >= hdr.max_pages * COFFEE_PAGE_SIZE ||
|
||||||
|
@ -937,11 +946,11 @@ cfs_seek(int fd, unsigned offset)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(coffee_fd_set[fd].end < offset) {
|
if(fdp->end < offset) {
|
||||||
coffee_fd_set[fd].end = offset;
|
fdp->end = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return coffee_fd_set[fd].offset = offset;
|
return fdp->offset = offset;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
|
@ -957,7 +966,7 @@ cfs_remove(const char *name)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
page = find_file(name);
|
page = find_file(name);
|
||||||
if(page < 0) {
|
if(page == INVALID_PAGE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,7 +1020,7 @@ cfs_read(int fd, void *buf, unsigned size)
|
||||||
if(r < 0) {
|
if(r < 0) {
|
||||||
r = remains > read_chunk ? read_chunk : remains;
|
r = remains > read_chunk ? read_chunk : remains;
|
||||||
COFFEE_READ((char *) buf + offset, r,
|
COFFEE_READ((char *) buf + offset, r,
|
||||||
ABS_OFFSET(fdp->file_page, base + offset));
|
absolute_offset(fdp->file_page, base + offset));
|
||||||
}
|
}
|
||||||
remains -= r;
|
remains -= r;
|
||||||
offset += r;
|
offset += r;
|
||||||
|
@ -1035,7 +1044,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
fdp = &coffee_fd_set[fd];
|
fdp = &coffee_fd_set[fd];
|
||||||
/* 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. */
|
||||||
while(size + fdp->offset + sizeof(struct file_header) >
|
while(size + fdp->offset + sizeof(struct file_header) >
|
||||||
fdp->max_pages * COFFEE_PAGE_SIZE) {
|
(fdp->max_pages * COFFEE_PAGE_SIZE)) {
|
||||||
update_eof_hint(fdp->file_page, fdp->end);
|
update_eof_hint(fdp->file_page, fdp->end);
|
||||||
if(merge_log(fdp->file_page, 1) < 0) {
|
if(merge_log(fdp->file_page, 1) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1062,7 +1071,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
COFFEE_WRITE(buf, size,
|
COFFEE_WRITE(buf, size,
|
||||||
ABS_OFFSET(fdp->file_page, fdp->offset));
|
absolute_offset(fdp->file_page, fdp->offset));
|
||||||
fdp->offset += size;
|
fdp->offset += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,7 +1140,7 @@ cfs_closedir(struct cfs_dir *dir)
|
||||||
int
|
int
|
||||||
cfs_coffee_reserve(const char *name, uint32_t size)
|
cfs_coffee_reserve(const char *name, uint32_t size)
|
||||||
{
|
{
|
||||||
return reserve(name, size, 0);
|
return reserve(name, page_count(size), 0);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
|
@ -1147,7 +1156,7 @@ cfs_coffee_configure_log(const char *file, unsigned log_size,
|
||||||
}
|
}
|
||||||
|
|
||||||
page = find_file(file);
|
page = find_file(file);
|
||||||
if(page < 0) {
|
if(page == INVALID_PAGE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue