Example #1
0
//------------------------------------------------------------------------------
// free a cluster chain
uint8_t SdVolume::freeChain(uint32_t cluster) {
  // clear free cluster location
  allocSearchStart_ = 2;

  do {
    uint32_t next;
    if (!fatGet(cluster, &next)) return false;

    // free cluster
    if (!fatPut(cluster, 0)) return false;

    cluster = next;
  } while (!isEOC(cluster));

  return true;
}
Example #2
0
//------------------------------------------------------------------------------
bool FatVolume::allocateCluster(uint32_t current, uint32_t* next) {
  uint32_t find = current ? current : m_allocSearchStart;
  uint32_t start = find;
  while (1) {
    find++;
    // If at end of FAT go to beginning of FAT.
    if (find > m_lastCluster) {
      find = 2;
    }
    uint32_t f;
    int8_t fg = fatGet(find, &f);
    if (fg < 0) {
      DBG_FAIL_MACRO;
      goto fail;
    }
    if (fg && f == 0) {
      break;
    }
    if (find == start) {
      // Can't find space checked all clusters.
      DBG_FAIL_MACRO;
      goto fail;
    }
  }
  // mark end of chain
  if (!fatPutEOC(find)) {
    DBG_FAIL_MACRO;
    goto fail;
  }
  if (current) {
    // link clusters
    if (!fatPut(current, find)) {
      DBG_FAIL_MACRO;
      goto fail;
    }
  } else {
    // Remember place for search start.
    m_allocSearchStart = find;
  }
  updateFreeClusterCount(-1);
  *next = find;
  return true;

fail:
  return false;
}
//------------------------------------------------------------------------------
// find a contiguous group of clusters
uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) 
{
  // start of group
  uint32_t bgnCluster;

  // flag to save place to start next search
  uint8_t setStart;

  // set search start cluster
  if (*curCluster) 
  {
    // try to make file contiguous
    bgnCluster = *curCluster + 1;

    // don't save new start location
    setStart = false;
  } 
  else 
  {
    // start at likely place for free cluster
    bgnCluster = allocSearchStart_;

    // save next search start if one cluster
    setStart = 1 == count;
  }
  // end of group
  uint32_t endCluster = bgnCluster;

  // last cluster of FAT
  uint32_t fatEnd = clusterCount_ + 1;

  // search the FAT for free clusters
  for (uint32_t n = 0;; n++, endCluster++) 
  {
    // can't find space checked all clusters
    if (n >= clusterCount_) return false;

    // past end - start from beginning of FAT
    if (endCluster > fatEnd) 
	{
      bgnCluster = endCluster = 2;
    }
    uint32_t f;
    if (!fatGet(endCluster, &f)) return false;

    if (f != 0) 
	{
      // cluster in use try next cluster as bgnCluster
      bgnCluster = endCluster + 1;
    } 
	else if ((endCluster - bgnCluster + 1) == count) 
	{
      // done - found space
      break;
    }
  }
  // mark end of chain
  if (!fatPutEOC(endCluster)) 
	  return false;

  // link clusters
  while (endCluster > bgnCluster) 
  {
    if (!fatPut(endCluster - 1, endCluster)) 
		return false;
    endCluster--;
  }
  if (*curCluster != 0) 
  {
    // connect chains
    if (!fatPut(*curCluster, bgnCluster)) 
		return false;
  }
  // return first cluster number to caller
  *curCluster = bgnCluster;

  // remember possible next free cluster
  if (setStart) 
	  allocSearchStart_ = bgnCluster + 1;

  return true;
}
Example #4
0
//------------------------------------------------------------------------------
// find a contiguous group of clusters
bool FatVolume::allocContiguous(uint32_t count, uint32_t* firstCluster) {
  // flag to save place to start next search
  bool setStart = true;
  // start of group
  uint32_t bgnCluster;
  // end of group
  uint32_t endCluster;
  // Start at cluster after last allocated cluster.
  uint32_t startCluster = m_allocSearchStart;
  endCluster = bgnCluster = startCluster + 1;

  // search the FAT for free clusters
  while (1) {
    // If past end - start from beginning of FAT.
    if (endCluster > m_lastCluster) {
      bgnCluster = endCluster = 2;
    }
    uint32_t f;
    int8_t fg = fatGet(endCluster, &f);
    if (fg < 0) {
      DBG_FAIL_MACRO;
      goto fail;
    }
    if (f || fg == 0) {
      // cluster in use try next cluster as bgnCluster
      bgnCluster = endCluster + 1;

      // don't update search start if unallocated clusters before endCluster.
      if (bgnCluster != endCluster) {
        setStart = false;
      }
    } else if ((endCluster - bgnCluster + 1) == count) {
      // done - found space
      break;
    }
    // Can't find space if all clusters checked.
    if (startCluster == endCluster) {
      DBG_FAIL_MACRO;
      goto fail;
    }
    endCluster++;
  }
  // remember possible next free cluster
  if (setStart) {
    m_allocSearchStart = endCluster + 1;
  }

  // mark end of chain
  if (!fatPutEOC(endCluster)) {
    DBG_FAIL_MACRO;
    goto fail;
  }
  // link clusters
  while (endCluster > bgnCluster) {
    if (!fatPut(endCluster - 1, endCluster)) {
      DBG_FAIL_MACRO;
      goto fail;
    }
    endCluster--;
  }
  // Maintain count of free clusters.
  updateFreeClusterCount(-count);

  // return first cluster number to caller
  *firstCluster = bgnCluster;
  return true;

fail:
  return false;
}