[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/at45db LogStorageP.nc, 1.1.2.9, 1.1.2.10

David Gay idgay at users.sourceforge.net
Thu Jun 1 09:35:55 PDT 2006


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv6503

Modified Files:
      Tag: tinyos-2_0_devel-BRANCH
	LogStorageP.nc 
Log Message:
better log storage implementation


Index: LogStorageP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/at45db/Attic/LogStorageP.nc,v
retrieving revision 1.1.2.9
retrieving revision 1.1.2.10
diff -C2 -d -r1.1.2.9 -r1.1.2.10
*** LogStorageP.nc	31 May 2006 23:34:45 -0000	1.1.2.9
--- LogStorageP.nc	1 Jun 2006 16:35:53 -0000	1.1.2.10
***************
*** 143,149 ****
  
    void readFromBeginning() {
!     /* Set position to end of page before first page, to force page advance
!        on next read */
!     s[client].rpos = 0;
      s[client].rpage = firstVolumePage() - 1;
      s[client].rend = s[client].roffset = 0;
--- 143,149 ----
  
    void readFromBeginning() {
!     /* Set position to page before first page and force advance to next
!        page on next read */
!     s[client].rpos = SEEK_BEGINNING;
      s[client].rpage = firstVolumePage() - 1;
      s[client].rend = s[client].roffset = 0;
***************
*** 168,176 ****
    }
  
!   void emptyLog() {
!     s[client].positionKnown = TRUE;
!     s[client].wpos = 0;
!     setWritePage(firstVolumePage()); 
!     readFromBeginning();
    }
  
--- 168,177 ----
    }
  
!   void wmetadataStart();
! 
!   void sync() {
!     metadata.flags = F_SYNC | F_LASTVALID;
!     metadata.lastRecordOffset = s[client].woffset;
!     wmetadataStart();
    }
  
***************
*** 185,189 ****
    void locateStart();
    void rmetadataStart();
-   void wmetadataStart();
    void seekStart();
  
--- 186,189 ----
***************
*** 259,263 ****
  
    command error_t LinearWrite.append[logstorage_t id](void* buf, storage_len_t length) {
!     return newRequest(R_APPEND, id, FALSE, buf, length);
    }
  
--- 259,272 ----
  
    command error_t LinearWrite.append[logstorage_t id](void* buf, storage_len_t length) {
!     if (len > call LinearRead.getSize[id]() - PAGE_SIZE)
!       /* Writes greater than the volume size are invalid.
! 	 Writes equal to the volume size could break the log volume
! 	 invariant (see next comment).
! 	 Writes that span the whole volume could lead to problems
! 	 at boot time (no valid block with a record boundary).
! 	 Refuse them all. */
!       return EINVAL;
!     else
!       return newRequest(R_APPEND, id, FALSE, buf, length);
    }
  
***************
*** 286,295 ****
    }
  
!   command storage_cookie_t LinearRead.getSize[logstorage_t id]() {
!     return call At45dbVolume.volumeSize[id]() * PAGE_SIZE;
    }
  
    command error_t CircularWrite.append[logstorage_t id](void* buf, storage_len_t length) {
!     return newRequest(R_APPEND, id, TRUE, buf, length);
    }
  
--- 295,313 ----
    }
  
!   command storage_len_t LinearRead.getSize[logstorage_t id]() {
!     return call At45dbVolume.volumeSize[id]() * (storage_len_t)PAGE_SIZE;
    }
  
    command error_t CircularWrite.append[logstorage_t id](void* buf, storage_len_t length) {
!     if (len > call CircularRead.getSize[id]() - PAGE_SIZE)
!       /* Writes greater than the volume size are invalid.
! 	 Writes equal to the volume size could break the log volume
! 	 invariant (see next comment).
! 	 Writes that span the whole volume could lead to problems
! 	 at boot time (no valid block with a record boundary).
! 	 Refuse them all. */
!       return EINVAL;
!     else
!       return newRequest(R_APPEND, id, TRUE, buf, length);
    }
  
***************
*** 318,322 ****
    }
  
!   command storage_cookie_t CircularRead.getSize[logstorage_t id]() {
      return call LinearRead.getSize[id]();
    }
--- 336,340 ----
    }
  
!   command storage_len_t CircularRead.getSize[logstorage_t id]() {
      return call LinearRead.getSize[id]();
    }
***************
*** 327,354 ****
  
    void eraseMetadataDone() {
!     emptyLog(); // reset write pointer
      endRequest(SUCCESS);
    }
  
!   void eraseContinue() {
!     /* We erase backwards. That leaves the first two pages in the cache */
!     if (lastPage == firstPage)
        {
! 	emptyLog();
! 	/* If we just reboot after erasing the flash, then the next attempt
! 	   to locate log boundaries will have to scan the while flash
! 	   (looking for a valid block). To reduce the chances of this, we
! 	   write a valid header in block 0 after erase. */
! 	metadata.flags = 0;
  	wmetadataStart();
        }
      else
!       call At45db.erase(--lastPage, AT45_ERASE);
    }
  
    void eraseStart() {
      firstPage = firstVolumePage();
      lastPage = lastVolumePage();
!     eraseContinue();
    }
  
--- 345,376 ----
  
    void eraseMetadataDone() {
!     s[client].positionKnown = TRUE;
!     s[client].wpos = PAGE_SIZE; // last page has offset 0 and is before us
!     s[client].circled = FALSE;
!     setWritePage(firstVolumePage()); 
!     readFromBeginning();
! 
      endRequest(SUCCESS);
    }
  
!   void eraseEraseDone() {
!     if (firstPage == lastPage - 1)
        {
! 	/* We create a valid, synced last page */
! 	metadata.flags = F_SYNC | F_LASTVALID;
! 	metadata.lastRecordOffset = 0;
! 	setWritePage(firstPage);
! 	s[client].wpos = 0;
  	wmetadataStart();
        }
      else
!       call At45db.erase(firstPage++, AT45_ERASE);
    }
  
    void eraseStart() {
+     s[client].positionKnown = FALSE; // in case erase fails
      firstPage = firstVolumePage();
      lastPage = lastVolumePage();
!     eraseEraseDone();
    }
  
***************
*** 359,406 ****
    void locateLastRecord();
  
-   at45page_t locateCurrentPage() {
-     return firstPage + ((lastPage - firstPage) >> 1);
-   }
- 
    void locateLastCrcDone(uint16_t crc) {
!     if (crc == metadata.crc)
        {
! 	/* We've found the last valid page with a record-end */
! 	s[client].positionKnown = TRUE;
! 	if (metadata.flags & F_SYNC) /* must start on next page */
! 	  {
! 	    setWritePage(firstPage + 1);
! 	    s[client].wpos = metadata.pos + PAGE_SIZE;
! 	  }
! 	else
! 	  {
! 	    s[client].wpage = firstPage;
! 	    s[client].woffset = metadata.lastRecordOffset;
! 	    s[client].wpos = metadata.pos + metadata.lastRecordOffset;
! 	  }
  
! 	/* If we're on the first pass (no F_CIRCLED flag), the read
! 	   pointer starts at the beginning of the flash. Otherwise,
! 	   we invalidate it, which will force read requests to find
! 	   the first valid page after the current write pointer. */
! 	s[client].circled = (metadata.flags & F_CIRCLED) != 0;
! 	if (s[client].circled)
! 	  {
! 	    if (!s[client].circular) // oops
! 	      {
! 		/* Maybe treating the log as empty would be better? */
! 		endRequest(FAIL);
! 		return;
! 	      }
  
! 	    invalidateReadPointer();
  	  }
- 	else
- 	  readFromBeginning();
  
! 	startRequest();
        }
      else
!       locateLastRecord();
    }
  
--- 381,427 ----
    void locateLastRecord();
  
    void locateLastCrcDone(uint16_t crc) {
!     if (crc != metadata.crc)
        {
! 	locateLastRecord();
! 	return;
!       }
  
!     /* We've found the last valid page with a record-end. Set up
!        the read and write positions. */
  
!     if (metadata.flags & F_SYNC) /* must start on next page */
!       {
! 	setWritePage(firstPage + 1);
! 	s[client].wpos = metadata.pos + PAGE_SIZE;
!       }
!     else
!       {
! 	s[client].wpage = firstPage;
! 	s[client].woffset = metadata.lastRecordOffset;
! 	s[client].wpos = metadata.pos + metadata.lastRecordOffset;
!       }
! 
!     /* If we're on the first pass (no F_CIRCLED flag), the read
!        pointer starts at the beginning of the flash. Otherwise,
!        we invalidate it, which will force read requests to find
!        the first valid page after the current write pointer. */
!     s[client].circled = (metadata.flags & F_CIRCLED) != 0;
!     if (s[client].circled)
!       {
! 	if (!s[client].circular) // oops
! 	  {
! 	    endRequest(FAIL);
! 	    return;
  	  }
  
! 	invalidateReadPointer();
        }
      else
!       readFromBeginning();
! 
!     /* And we can now proceed to the real request */
!     s[client].positionKnown = TRUE;
!     startRequest();
    }
  
***************
*** 413,424 ****
  
    void locateLastRecord() {
!     if (firstPage == firstVolumePage())
        {
! 	/* There were no valid pages with a record end */
! 	emptyLog();
! 	startRequest();
        }
      else
!       readMetadata(--firstPage);
    }
  
--- 434,451 ----
  
    void locateLastRecord() {
!     if (firstPage == lastPage)
        {
! 	/* We walked all the way back to the last page, and it's not 
! 	   valid. The log-volume invariant is not holding. Fail out. */
! 	endRequest(FAIL);
! 	return;
        }
+ 
+     if (firstPage == firstVolumePage())
+       firstPage = lastPage;
      else
!       firstPage--;
! 
!     readMetadata(firstPage);
    }
  
***************
*** 427,433 ****
--- 454,465 ----
      /* firstPage is one after last valid page, but the last page with
         a record end may be some pages earlier. Search for it. */
+     lastPage = lastVolumePage() - 1;
      locateLastRecord();
    }
  
+   at45page_t locateCurrentPage() {
+     return firstPage + ((lastPage - firstPage) >> 1);
+   }
+ 
    void locateBinarySearch() {
      if (lastPage <= firstPage)
***************
*** 465,493 ****
  
    void locateFirstCrcDone(uint16_t crc) {
-     firstPage++;
      if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)
!       {
! 	metaState = META_LOCATE;
! 	/* We track the page with the largest position found. */
! 	s[client].wpos = metadata.pos;
! 	/* We now know that the valid pages span a contiguous sequence
! 	   starting at firstPage - 1. The binary search will look for
! 	   the page with the largest position. */
! 	locateBinarySearch();
!       }
!     else if (firstPage != lastPage)
!       /* Try the next page. There can be an arbitrary number of
! 	 consecutive bad pages (see discussion at start of this file) */
!       readMetadata(firstPage);
      else
!       {
! 	/* Found no valid page. We might want to give up after some
! 	   bounded number of pages, rather than checking the whole
! 	   log -- many bad consecutive pages is extremely unlikely and
! 	   probably indicates a major problem somewhere. */
! 	emptyLog();
! 	startRequest();
!       }
!     
    }
  
--- 497,507 ----
  
    void locateFirstCrcDone(uint16_t crc) {
      if (metadata.magic == PERSISTENT_MAGIC && crc == metadata.crc)
!       s[client].wpos = metadata.pos;
      else
!       s[client].wpos = 0;
! 
!     metaState = META_LOCATE;
!     locateBinarySearch();
    }
  
***************
*** 500,505 ****
      metaState = META_LOCATEFIRST;
      firstPage = firstVolumePage();
!     lastPage = lastVolumePage();
!     readMetadata(firstPage);
    }
  
--- 514,519 ----
      metaState = META_LOCATEFIRST;
      firstPage = firstVolumePage();
!     lastPage = lastVolumePage() - 1;
!     readMetadata(lastPage);
    }
  
***************
*** 551,559 ****
  
    void appendStart() {
!     /* Set lastRecordOffset in case we need to write metadata (see
!        wmetadataStart) */
!     metadata.lastRecordOffset = s[client].woffset;
!     metadata.flags = F_LASTVALID;
!     appendContinue();
    }
  
--- 565,588 ----
  
    void appendStart() {
!     storage_len_t vlen = (storage_len_t)npages() * PAGE_SIZE;
! 
!     /* 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.
! 
!        Note that >= in the if below means we won't write a record that
!        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)
!       sync();
!     else
!       {
! 	/* Set lastRecordOffset in case we need to write metadata (see
! 	   wmetadataStart) */
! 	metadata.lastRecordOffset = s[client].woffset;
! 	metadata.flags = F_LASTVALID;
! 	appendContinue();
!       }
    }
  
***************
*** 566,574 ****
        endRequest(SUCCESS);
      else
!       {
! 	metadata.flags = F_SYNC | F_LASTVALID;
! 	metadata.lastRecordOffset = s[client].woffset;
! 	wmetadataStart();
!       }
    }
  
--- 595,599 ----
        endRequest(SUCCESS);
      else
!       sync();
    }
  
***************
*** 622,626 ****
    void wmetadataWriteDone() {
      metaState = META_IDLE;
!     if (s[client].request == R_SYNC)
        call At45db.sync(firstPage);
      else
--- 647,651 ----
    void wmetadataWriteDone() {
      metaState = META_IDLE;
!     if (metadata.flags & F_SYNC)
        call At45db.sync(firstPage);
      else
***************
*** 700,716 ****
        firstPage = firstVolumePage();
      if (firstPage == s[client].wpage)
!       {
! 	if (!s[client].rvalid)
! 	  /* We cannot find a record boundary to start at (we've just
! 	     walked through the whole log...). Give up. */
! 	  endRequest(SUCCESS);
! 	else
! 	  {
! 	    /* The current write page has no metadata yet, so we fake it */
! 	    metadata.flags = 0;
! 	    metadata.pos = s[client].wpos - s[client].woffset;
! 	    continueReadAt(0);
! 	  }
!       }
      else
        readMetadata(firstPage);
--- 725,739 ----
        firstPage = firstVolumePage();
      if (firstPage == s[client].wpage)
!       if (!s[client].rvalid)
! 	/* We cannot find a record boundary to start at (we've just
! 	   walked through the whole log...). Give up. */
! 	endRequest(SUCCESS);
!       else
! 	{
! 	  /* The current write page has no metadata yet, so we fake it */
! 	  metadata.flags = 0;
! 	  metadata.pos = s[client].wpos - s[client].woffset;
! 	  continueReadAt(0);
! 	}
      else
        readMetadata(firstPage);
***************
*** 768,772 ****
      invalidateReadPointer(); // default to beginning of log
  
!     if (offset > s[client].wpos)
        {
  	endRequest(EINVAL);
--- 791,800 ----
      invalidateReadPointer(); // default to beginning of log
  
!     /* The write positions are offset by PAGE_SIZE (see emptyLog) */
! 
!     if (offset == SEEK_BEGINNING)
!       offset = PAGE_SIZE;
! 
!     if (offset > s[client].wpos || offset < PAGE_SIZE)
        {
  	endRequest(EINVAL);
***************
*** 778,783 ****
         page's metadata.pos field matches the cookie's value */
      s[client].rpos = offset;
!     s[client].roffset = offset % PAGE_SIZE;
!     s[client].rpage = firstVolumePage() + (offset / PAGE_SIZE) % npages();
      s[client].rend = PAGE_SIZE; // default to no sync flag
  
--- 806,811 ----
         page's metadata.pos field matches the cookie's value */
      s[client].rpos = offset;
!     s[client].roffset = (offset - PAGE_SIZE) % PAGE_SIZE;
!     s[client].rpage = firstVolumePage() + ((offset - PAGE_SIZE) / PAGE_SIZE) % npages();
      s[client].rend = PAGE_SIZE; // default to no sync flag
  
***************
*** 809,813 ****
  	endRequest(FAIL);
        else
! 	eraseContinue();
    }
  
--- 837,841 ----
  	endRequest(FAIL);
        else
! 	eraseEraseDone();
    }
  
***************
*** 828,833 ****
        if (error != SUCCESS)
  	endRequest(FAIL);
!       else
! 	syncMetadataDone();
    }
  
--- 856,865 ----
        if (error != SUCCESS)
  	endRequest(FAIL);
!       else switch (s[client].request)
! 	{
! 	case R_ERASE: eraseMetadataDone(); break;
! 	case R_APPEND: appendStart(); break;
! 	case R_SYNC: syncMetadataDone(); break;
! 	}
    }
  
***************
*** 836,841 ****
        if (error != SUCCESS)
  	endRequest(FAIL);
-       else if (s[client].request == R_ERASE)
- 	eraseMetadataDone();
        else
  	appendMetadataDone();
--- 868,871 ----



More information about the Tinyos-2-commits mailing list