예제 #1
0
////////////////////////////////////////////////////
// SAVE ALL CONFIG TO EEPROM
void storage_write_patch()
{
	int len = 0;
	eeprom_write(0, MAGIC_COOKIE);
	int storage_ofs = 1;
	storage_write(global_storage(&len), len, &storage_ofs);
	storage_write(stack_storage(&len), len, &storage_ofs);
	storage_write(cv_storage(&len), len, &storage_ofs);
	storage_write(gate_storage(&len), len, &storage_ofs);
}
예제 #2
0
// Clears the current page
// Does not clear if:
//  - Previous page was cleared already
//  - Flash is entirely empty (no reason to clear)
// storage_init() must be called first
//
// Returns:
//  0 - Page was not cleared
//  1 - Page was cleared
uint8_t storage_clear_page()
{
	// Flash is empty
	if ( current_page == 0 && current_storage_index == 0 )
	{
		// Flash is full, needs to be erased which is the same as clearing a page
		if ( storage_erase_flash() )
		{
			return 1;
		}
		return 0;
	}

	// Previous page was completely cleared
	if ( current_storage_index == 0 && cleared_block == 1 )
	{
		return 0;
	}

	// Clear the rest of the blocks in the page
	// Write a 0'd out buffer as well
	uint8_t temp_buffer[STORAGE_SIZE];
	memset( temp_buffer, 0, STORAGE_SIZE );
	while ( current_storage_index != 0 )
	{
		if ( storage_write( temp_buffer, 0, STORAGE_SIZE, 1 ) == 0 )
		{
			// This is bad...not possible to recover without manually clearing
			print("Not enough room in buffer, failed to clear block.");
			return 0;
		}
	}

	return 1;
}
예제 #3
0
파일: persistent.c 프로젝트: KaSt/nereamud
//
// store a room in the persistent database
void worldStorePersistentRoom(WORLD_DATA *world, const char *key,
			      ROOM_DATA *room) {
  static char fname[MAX_BUFFER];
  static char  dir1[SMALL_BUFFER];
  static char  dir2[SMALL_BUFFER];
  if(!*key)
    return;

  unsigned long hash1 = pearson_hash8_1(key) % WORLD_BINS;
  unsigned long hash2 = pearson_hash8_2(key) % WORLD_BINS;
  *fname = '\0';
  *dir1  = '\0';
  *dir2  = '\0';

  // make sure our hash bins exist
  sprintf(dir1, "%s/persistent/%lu", 
	  worldGetPath(world), hash1);
  if(!dir_exists(dir1))
    mkdir(dir1, S_IRWXU | S_IRWXG);

  // and the second one as well
  sprintf(dir2, "%s/persistent/%lu/%lu", 
	  worldGetPath(world), hash1, hash2);
  if(!dir_exists(dir2))
    mkdir(dir2, S_IRWXU | S_IRWXG);

  // now, store the room
  sprintf(fname, "%s/persistent/%lu/%lu/%s", 
	  worldGetPath(world), hash1, hash2, key);
  STORAGE_SET *set = roomStore(room);
  storage_write(set, fname);
  storage_close(set);

  // log_string("stored persistent room :: %s", fname);
}
예제 #4
0
uint64_t storage_block_fill_write(struct storage_media *media, uint64_t start,
	uint64_t count, uint32_t fill_pattern)
{
	if (storage_block_setup(media, start, count, 0) == 0)
		return 0;

	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
	uint64_t block_size = media->write_bl_len;
	/*
	 * We allocate max 4 MiB buffer on heap and set it to fill_pattern and
	 * perform mmc_write operation using this 4MiB buffer until requested
	 * size on disk is written by the fill byte.
	 *
	 * 4MiB was chosen after repeating several experiments with the max
	 * buffer size to be used. Using 1 lba i.e. block_size buffer results in
	 * very large fill_write time. On the other hand, choosing 4MiB, 8MiB or
	 * even 128 Mib resulted in similar write times. With 2MiB, the
	 * fill_write time increased by several seconds. So, 4MiB was chosen as
	 * the default max buffer size.
	 */
	uint64_t heap_lba = (4 * MiB) / block_size;
	/*
	 * Actual allocated buffer size is minimum of three entities:
	 * 1) 4MiB equivalent in lba
	 * 2) count: Number of lbas to overwrite
	 * 3) ctrlr->b_max: Max lbas that the block device allows write
	 * operation on at a time.
	 */
	uint64_t buffer_lba = MIN(MIN(heap_lba, count), ctrlr->b_max);

	uint64_t buffer_bytes = buffer_lba * block_size;
	uint64_t buffer_words = buffer_bytes / sizeof(uint32_t);
	uint32_t *buffer = malloc(buffer_bytes);
	uint32_t *ptr = buffer;

	for (; buffer_words ; buffer_words--)
		*ptr++ = fill_pattern;

	uint64_t todo = count;
	int ret = 0;

	do {
		uint64_t curr_lba = MIN(buffer_lba, todo);

		if (storage_write(media, start, curr_lba, buffer) != curr_lba)
			goto cleanup;
		todo -= curr_lba;
		start += curr_lba;
	} while (todo > 0);

	ret = count;

cleanup:
	free(buffer);
	return ret;
}
예제 #5
0
uint8_t storage_save_settings() {
	uint8_t buffer[STORAGE_SIZE];
	uint8_t offset = 0;
	for (uint8_t i=0; i<module_count; i++) {
		storage_modules[i]->onSave();
		memcpy(buffer+offset, storage_modules[i]->settings, storage_modules[i]->size);
		offset += storage_modules[i]->size;
	}
	return storage_write(buffer, 0, sizeof(buffer), 0) == 1;
}
예제 #6
0
파일: pystorage.c 프로젝트: KaSt/nereamud
//
// write the set to file
PyObject *PyStorageSet_write      (PyObject *self, PyObject *args) { 
  char *fname = NULL;
  if(!PyArg_ParseTuple(args, "s", &fname)) {
    PyErr_Format(PyExc_TypeError, 
		 "Filenames must be in string form");
    return NULL;
  }
  storage_write(((PyStorageSet *)self)->set, fname);
  return Py_BuildValue("i", 1);
}
예제 #7
0
파일: sproto_nb.c 프로젝트: dcasier/rozofs
void sp_write_1_svc_nb(void * pt, rozorpc_srv_ctx_t *req_ctx_p) {
    sp_write_arg_t * args = (sp_write_arg_t *) pt;
    static sp_write_ret_t ret;
    storage_t *st = 0;
    // Variable to be used in a later version.
    uint8_t version = 0;
    char *buf_bins;
    
    /*
    ** put  the pointer to the bins (still in received buffer
    */
    int position = storage_get_position_of_first_byte2write_from_write_req();
    buf_bins = (char*)ruc_buf_getPayload(req_ctx_p->recv_buf);
    buf_bins+= position;


    DEBUG_FUNCTION;

    START_PROFILING_IO(write, args->nb_proj * rozofs_get_max_psize(args->layout)
            * sizeof (bin_t));

    ret.status = SP_FAILURE;

    // Get the storage for the couple (cid;sid)
    if ((st = storaged_lookup(args->cid, args->sid)) == 0) {
        ret.sp_write_ret_t_u.error = errno;
        goto out;
    }

    // Write projections
    if (storage_write(st, args->layout, (sid_t *) args->dist_set, args->spare,
            (unsigned char *) args->fid, args->bid, args->nb_proj, version,
            &ret.sp_write_ret_t_u.file_size,
            (bin_t *) buf_bins) <= 0) {
        ret.sp_write_ret_t_u.error = errno;
        goto out;
    }

    ret.status = SP_SUCCESS;
out:
 
    req_ctx_p->xmitBuf  = req_ctx_p->recv_buf;
    req_ctx_p->recv_buf = NULL;
    rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); 
    /*
    ** release the context
    */
    rozorpc_srv_release_context(req_ctx_p);
    STOP_PROFILING(write);
    return ;
}
// Start the write of a checksummed structure
void data_services_write(void)
{
	if (data_services_table_index >= mavlink_parameter_block_count)
	{
		if (data_services_user_callback != NULL) data_services_user_callback(true);
		data_services_user_callback = NULL;
		data_service_state = DATA_SERVICE_STATE_WAITING;
		return;
	}

	uint16_t size = serialise_items_to_buffer(data_services_table_index);

	if (size == 0)
	{
		if (data_services_user_callback != NULL) data_services_user_callback(false);
		data_services_user_callback = NULL;
		data_service_state = DATA_SERVICE_STATE_WAITING;
		return;
	}

	uint16_t handle = mavlink_parameter_blocks[data_services_table_index].data_storage_area;
	//data_services_calc_item_size(data_services_table_index);
	uint16_t type = DATA_STORAGE_CHECKSUM_STRUCT;

	// TODO: Check here if data handle is ok
	//storage_check_area_exists

	if ((type == DATA_STORAGE_CHECKSUM_STRUCT) && 
	    ((data_services_serialize_flags & mavlink_parameter_blocks[data_services_table_index].data_storage_flags) ||
	    (data_services_serialize_flags & STORAGE_FLAG_ALL)))
	{
		if (storage_write(handle, data_services_buffer, size, &data_services_write_callback) == true)
		{
			data_service_state = DATA_SERVICE_STATE_WRITE_WAITING;
			return;
		}
	}
	else
	{
		if (data_services_do_all_areas == true)
			data_services_table_index++;
		else
		{
			if (data_services_user_callback != NULL) data_services_user_callback(false);
			data_services_user_callback = NULL;
			data_service_state = DATA_SERVICE_STATE_WAITING;
		}
	}
}
예제 #9
0
uint64_t storage_block_write(struct storage_media *media, uint64_t start,
	uint64_t count, const void *buffer)
{
	const uint8_t *src = (const uint8_t *)buffer;

	if (storage_block_setup(media, start, count, 0) == 0)
		return 0;

	uint64_t todo = count;
	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
	do {
		uint64_t cur = MIN(todo, ctrlr->b_max);
		if (storage_write(media, start, cur, src) != cur)
			return 0;
		todo -= cur;
		start += cur;
		src += cur * media->write_bl_len;
	} while (todo > 0);
	return count;
}
예제 #10
0
파일: socials.c 프로젝트: KaSt/nereamud
//
// save all of the socials to disk
//
void save_socials() {
  STORAGE_SET       *set = new_storage_set();
  LIST         *soc_list = newList();

  // iterate across the social table and save all of the unique socials
  HASH_ITERATOR  *hash_i = newHashIterator(social_table);
  const char        *cmd = NULL;
  SOCIAL_DATA      *data = NULL;

  ITERATE_HASH(cmd, data, hash_i)
    listPut(soc_list, data);
  deleteHashIterator(hash_i);

  store_list(set, "socials", gen_store_list(soc_list, socialStore));
  deleteList(soc_list);

  // write the set
  storage_write(set, SOCIALS_FILE);
  
  // close the set
  storage_close(set);
}
예제 #11
0
파일: sproto.c 프로젝트: weixu8/rozofs
sp_status_ret_t *sp_write_1_svc(sp_write_arg_t * args, struct svc_req * req) {
    static sp_status_ret_t ret;
    storage_t *st = 0;
    DEBUG_FUNCTION;

    START_PROFILING_IO(write,
            args->nrb * rozofs_psizes[args->tid] * sizeof (bin_t));

    ret.status = SP_FAILURE;
    if ((st = storaged_lookup(args->sid)) == 0) {
        ret.sp_status_ret_t_u.error = errno;
        goto out;
    }
    if (storage_write
        (st, args->fid, args->tid, args->bid, args->nrb, args->bins.bins_len,
         (bin_t *) args->bins.bins_val) != 0) {
        ret.sp_status_ret_t_u.error = errno;
        goto out;
    }
    ret.status = SP_SUCCESS;
out:
    STOP_PROFILING(write);
    return &ret;
}
예제 #12
0
static inline void
main_menue (uint8_t cmd)
{
  TLogfileBeaconPacket pkt;

  /* ignore non-printable characters */
  if (cmd <= ' ')
    return;
  /* show key pressed */
  debug_printf ("%c\n", cmd);
  /* map lower case to upper case */
  if (cmd > 'a' && cmd < 'z')
    cmd -= ('a' - 'A');

  switch (cmd)
    {
    case '?':
    case 'H':
      debug_printf ("\n"
		    " *****************************************************\n"
		    " * OpenBeacon Tag - Bluetooth Console\n"
		    " *                  Version v" PROGRAM_VERSION "\n"
		    " * (C) 2011 Milosch Meriac <*****@*****.**>\n"
		    " *****************************************************\n"
		    " * H,?          - this help screen\n"
		    " * S            - Show device status\n"
		    " *\n"
		    " * E            - Erase Storage\n"
		    " * W            - Test Write Storage\n"
		    " * R            - Test Read Storage\n"
		    " * F            - Test WriteFill Storage\n"
		    " * M            - write 3 times and read them\n"
		    " *****************************************************\n"
		    "\n");
      break;
    case 'S':
      debug_printf ("\n"
		    " *****************************************************\n"
		    " * OpenBeacon Status Information                     *\n"
		    " *****************************************************\n");
      show_version ();
      spi_status ();
      acc_status ();
      storage_status ();
      debug_printf (" *****************************************************\n"
		    "\n");
      break;
  



    case 'M' :
	{
	uint32_t counter;
	debug_printf ("\nErasing Storage...\n\n");
	storage_erase ();
	debug_printf ("\nWriting Khalil 3 times...\n");
	counter = 0;
	const char data[] = "Khalil";
	const uint8_t buffer[32];
	while(counter < 3)
	{
	  storage_write (counter*sizeof(buffer), sizeof (buffer), &data);
	  counter ++;
	}
	debug_printf ("\n[DONE]\n");

	debug_printf("\n reading the data...\n");

	counter = 0;

	while(counter < 3)
	{
	storage_read (counter*sizeof(buffer), counter*sizeof(buffer) + sizeof (buffer), &buffer);
	hex_dump (buffer,0,sizeof (buffer));
	counter++;
	}

	break;
      }



    case 'E':
      debug_printf ("\nErasing Storage...\n\n");
      storage_erase ();
      g_storage_items = 0;
      break;

    case 'W':
      {
	const char hello[] = "Hello World!";
	debug_printf ("\n * writing '%s' (%i bytes)\n", hello,
		      sizeof (hello));
	storage_write (0, sizeof (hello), &hello);
      }
      break;

    case 'R':
      {
	const uint8_t buffer[32];
	debug_printf ("\n * reading %i bytes\n", sizeof (buffer));
	storage_read (0, sizeof (buffer), &buffer);
	hex_dump (buffer, 0, sizeof (buffer));
      }
      break;

    case 'F':
      {
	uint32_t counter;
	debug_printf ("\nErasing Storage...\n\n");
	storage_erase ();
	debug_printf ("\nFilling Storage...\n");
	counter = 0;
	while(counter < LOGFILE_STORAGE_SIZE)
	{
	  pkt.time = htonl(counter);
	  pkt.oid = htons(counter / sizeof(pkt));
	  pkt.strength = (counter / sizeof(pkt)) % MAX_POWER_LEVELS;
	  pkt.crc = crc8 (((uint8_t *) & pkt), sizeof (pkt) - sizeof (pkt.crc));
	  storage_write (counter, sizeof (pkt), &pkt);

	  counter += sizeof(pkt);
	}
	debug_printf ("\n[DONE]\n");
	break;
      }

    default:
      debug_printf ("Unknown command '%c' - please press 'H' for help \n",
		    cmd);
    }
  debug_printf ("\n# ");
}
예제 #13
0
static void *storage_write_thread(void *arg) {
    void *storage = arg;
    // NOTE: ignoring overflow since that would take years of uptime in a
    // specific load pattern of never going to sleep.
    unsigned int backoff[MAX_NUMBER_OF_SLAB_CLASSES] = {0};
    unsigned int counter = 0;
    useconds_t to_sleep = WRITE_SLEEP_MIN;
    logger *l = logger_create();
    if (l == NULL) {
        fprintf(stderr, "Failed to allocate logger for storage compaction thread\n");
        abort();
    }

    pthread_mutex_lock(&storage_write_plock);

    while (1) {
        // cache per-loop to avoid calls to the slabs_clsid() search loop
        int min_class = slabs_clsid(settings.ext_item_size);
        bool do_sleep = true;
        counter++;
        if (to_sleep > WRITE_SLEEP_MAX)
            to_sleep = WRITE_SLEEP_MAX;

        for (int x = 0; x < MAX_NUMBER_OF_SLAB_CLASSES; x++) {
            bool did_move = false;
            bool mem_limit_reached = false;
            unsigned int chunks_free;
            int item_age;
            int target = settings.ext_free_memchunks[x];
            if (min_class > x || (backoff[x] && (counter % backoff[x] != 0))) {
                // Long sleeps means we should retry classes sooner.
                if (to_sleep > WRITE_SLEEP_MIN * 10)
                    backoff[x] /= 2;
                continue;
            }

            // Avoid extra slab lock calls during heavy writing.
            chunks_free = slabs_available_chunks(x, &mem_limit_reached,
                    NULL, NULL);

            // storage_write() will fail and cut loop after filling write buffer.
            while (1) {
                // if we are low on chunks and no spare, push out early.
                if (chunks_free < target && mem_limit_reached) {
                    item_age = 0;
                } else {
                    item_age = settings.ext_item_age;
                }
                if (storage_write(storage, x, item_age)) {
                    chunks_free++; // Allow stopping if we've done enough this loop
                    did_move = true;
                    do_sleep = false;
                    if (to_sleep > WRITE_SLEEP_MIN)
                        to_sleep /= 2;
                } else {
                    break;
                }
            }

            if (!did_move) {
                backoff[x]++;
            } else if (backoff[x]) {
                backoff[x] /= 2;
            }
        }

        // flip lock so we can be paused or stopped
        pthread_mutex_unlock(&storage_write_plock);
        if (do_sleep) {
            usleep(to_sleep);
            to_sleep *= 2;
        }
        pthread_mutex_lock(&storage_write_plock);
    }
    return NULL;
}