Beispiel #1
0
/*---------------------------------------------------------------------------*/
static struct file *
find_file(const char *name)
{
  int i;
  struct file_header hdr;
  coffee_page_t page;
  
  /* First check if the file metadata is cached. */
  for(i = 0; i < COFFEE_MAX_OPEN_FILES; i++) {
    if(FILE_FREE(&coffee_files[i])) {
      continue;
    }

    read_header(&hdr, coffee_files[i].page);
    if(HDR_ACTIVE(hdr) && !HDR_LOG(hdr) && strcmp(name, hdr.name) == 0) {
      return &coffee_files[i];
    }
  }
  
  /* Scan the flash memory sequentially otherwise. */
  for(page = 0; page < COFFEE_PAGE_COUNT; page = next_file(page, &hdr)) {
    read_header(&hdr, page);
    if(HDR_ACTIVE(hdr) && !HDR_LOG(hdr) && strcmp(name, hdr.name) == 0) {
      return load_file(page, &hdr);
    }
  }

  return NULL;
}
Beispiel #2
0
/*---------------------------------------------------------------------------*/
int
cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record)
{
  struct file_header hdr;
  coffee_page_t page;

  memcpy(&page, dir->dummy_space, sizeof(coffee_page_t));

  while(page < COFFEE_PAGE_COUNT) {
    read_header(&hdr, page);
    if(HDR_ACTIVE(hdr) && !HDR_LOG(hdr)) {
      coffee_page_t next_page;
      memcpy(record->name, hdr.name, sizeof(record->name));
      record->name[sizeof(record->name) - 1] = '\0';
      record->size = file_end(page);

      next_page = next_file(page, &hdr);
      memcpy(dir->dummy_space, &next_page, sizeof(coffee_page_t));
      return 0;
    }
    page = next_file(page, &hdr);
  }

  return -1;
}
Beispiel #3
0
/*---------------------------------------------------------------------------*/
static int
remove_by_page(coffee_page_t page, int remove_log, int close_fds)
{
  struct file_header hdr;
  int i;

  read_header(&hdr, page);
  if(!HDR_ACTIVE(hdr)) {
    return -1;
  }

  if(remove_log && HDR_MODIFIED(hdr)) {
    if(remove_by_page(hdr.log_page, 0, 0) < 0) {
      return -1;
    }
  }

  hdr.flags |= HDR_FLAG_OBSOLETE;
  write_header(&hdr, page);

  *gc_wait = 0;

  /* Close all file descriptors that reference the removed file. */
  if(close_fds) {
    for(i = 0; i < COFFEE_FD_SET_SIZE; i++) {
      if(coffee_fd_set[i].file != NULL && coffee_fd_set[i].file->page == page) {
	coffee_fd_set[i].flags = COFFEE_FD_FREE;
      }
    }
  }

  for(i = 0; i < COFFEE_MAX_OPEN_FILES; i++) {
    if(coffee_files[i].page == page) {
      coffee_files[i].page = INVALID_PAGE;
      coffee_files[i].references = 0;
      coffee_files[i].max_pages = 0;
    }
  }

#if !COFFEE_CONF_EXTENDED_WEAR_LEVELLING
  if(!HDR_LOG(hdr)) {
    collect_garbage(GC_RELUCTANT);
  }
#endif

  return 0;
}
/*---------------------------------------------------------------------------*/
int
cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record)
{
    struct file_header hdr;
    coffee_page_t page;

    for(page = *(coffee_page_t *)dir->dummy_space; page < COFFEE_PAGE_COUNT;) {
        watchdog_periodic();
        read_header(&hdr, page);
        if(HDR_ACTIVE(hdr) && !HDR_LOG(hdr)) {
            memcpy(record->name, hdr.name, sizeof(record->name));
            record->name[sizeof(record->name) - 1] = '\0';
            record->size = file_end(page);
            *(coffee_page_t *)dir->dummy_space = next_file(page, &hdr);
            return 0;
        }
        page = next_file(page, &hdr);
    }

    return -1;
}