-/* tab:4
+/*
* "Copyright (c) 2000-2004 The Regents of the University of California.
* All rights reserved.
*
uint8_t client = NO_CLIENT;
uint8_t metaState;
+ bool recordsLost;
at45page_t firstPage, lastPage;
storage_len_t len;
nx_struct pageinfo metadata;
void sync() {
metadata.flags = F_SYNC | F_LASTVALID;
metadata.lastRecordOffset = s[client].woffset;
+ /* rend is now no longer the end of the page */
+ if (s[client].rpage == s[client].wpage)
+ s[client].rend = s[client].woffset;
wmetadataStart();
}
switch (request)
{
case R_ERASE: signal LogWrite.eraseDone[c](ok); break;
- case R_APPEND: signal LogWrite.appendDone[c](ptr, actualLen, ok); break;
+ case R_APPEND: signal LogWrite.appendDone[c](ptr, actualLen, recordsLost, ok); break;
case R_SYNC: signal LogWrite.syncDone[c](ok); break;
case R_READ: signal LogRead.readDone[c](ptr, actualLen, ok); break;
case R_SEEK: signal LogRead.seekDone[c](ok); break;
}
command error_t LogRead.seek[uint8_t id](storage_cookie_t offset) {
- return newRequest(R_SEEK, id, (void *)(offset >> 16), offset);
+ return newRequest(R_SEEK, id, (void *)((uint16_t)(offset >> 16)), offset);
}
command storage_len_t LogRead.getSize[uint8_t id]() {
s[client].woffset += count;
len -= count;
+ /* We normally lose data at the point we make the first write to a
+ page in a log that has circled. */
+ if (offset == 0 && s[client].circled)
+ recordsLost = TRUE;
+
call At45db.write(s[client].wpage, offset, buf, count);
}
void appendStart() {
storage_len_t vlen = (storage_len_t)npages() * PAGE_SIZE;
+ recordsLost = FALSE;
+
/* If request would span the end of the flash, sync, to maintain the
invariant that the last flash page is synced and that either
the first or last pages are valid.
would end on the last byte of the last page, as this would mean that
we would not sync the last page, breaking the log volume
invariant */
- if (s[client].wpos % vlen >= vlen - len)
+ if ((s[client].wpos - PAGE_SIZE) % vlen >= vlen - len)
sync();
else
{
s[client].rpage = s[client].wpage;
else
{
- /* resume writing at the beginning of the first page */
+ /* resume reading at the beginning of the first page */
s[client].rvalid = TRUE;
s[client].rpage = lastVolumePage() - 1;
}
event void At45db.copyPageDone(error_t error) { }
- default event void LogWrite.appendDone[uint8_t logId](void* buf, storage_len_t l, error_t error) { }
+ default event void LogWrite.appendDone[uint8_t logId](void* buf, storage_len_t l, bool rLost, error_t error) { }
default event void LogWrite.eraseDone[uint8_t logId](error_t error) { }
default event void LogWrite.syncDone[uint8_t logId](error_t error) { }
default event void LogRead.readDone[uint8_t logId](void* buf, storage_len_t l, error_t error) { }
default command at45page_t At45dbVolume.remap[uint8_t logId](at45page_t volumePage) {return 0;}
default command at45page_t At45dbVolume.volumeSize[uint8_t logId]() {return 0;}
default async command error_t Resource.request[uint8_t logId]() {return SUCCESS;}
- default async command void Resource.release[uint8_t logId]() { }
+ default async command error_t Resource.release[uint8_t logId]() { return FAIL; }
}