void close_eraseblks(fs_context& fs) { /* TODO: Error handling missing! */ for (eb_id_t eb_id = 1; eb_id < fs.neraseblocks; ++eb_id) { if (fs.eb_usage[eb_id].e_type == eraseblock_type::ebin) continue; /* can never be "open" */ if (fs.eb_usage[eb_id].e_type == eraseblock_type::empty) continue; /* can never be "open" */ eraseblock_type eb_type = fs.eb_usage[eb_id].e_type; unsigned int writeops = get_be16(fs.eb_usage[eb_id].e_writeops); unsigned int max_writeops = fs.erasesize / fs.clustersize; if (writeops == max_writeops) continue; /* erase block is already finalized/closed */ fs.eb_usage[eb_id].e_writeops = put_be16(max_writeops); if (!summary_required(fs, eb_type)) continue; summary* eb_summary = summary_get(*fs.summary_cache, eb_type); summary_write(fs, eb_summary, eb_id); summary_close(*fs.summary_cache, eb_summary); /* tell gcinfo an erase block of a specific type was written */ unsigned int write_time = gcinfo_update_writetime(fs, eb_type); fs.eb_usage[eb_id].e_lastwrite = put_be16(write_time); } }
static double point_obs_measure( const point_obs_type * point_obs , const void * state , int iobs , node_id_type node_id) { if (point_obs->source_type == SOURCE_FIELD) { const field_type * field = field_safe_cast_const( state ); return field_iget_double(field , point_obs->active_index); } else if (point_obs->source_type == SOURCE_SUMMARY) { const container_type * container = container_safe_cast_const( state ); const summary_type * summary = summary_safe_cast_const( container_iget_node( container , iobs )); return summary_get( summary , node_id.report_step , node_id.state ); } else { util_abort("%s: unknown source type: %d \n",__func__, point_obs->source_type ); return -1; } }
void commit_write_operation(fs_context& fs, eraseblock_type eb_type, eb_id_t eb_id, be32_t ino_no) { /* TODO: Error handling missing! */ // This function cannot trigger garbage collection by itself because // calling functions may have to perform further operations to bring // the file system into a consistent state. One (and currently the // only) example is: // This function does not know whether a cluster was just written // that replaces (invalidates) a cluster in the same or another // erase block. In this case the calling function has to decrement // the old erase blocks valid cluster count. // To help triggering gc the function will increment fs.eb_written // every time an erase block was finalized. if (eb_type == eraseblock_type::ebin) { // Erase block indirect data is easy to handle. // It can never be "open" because it is always completely // written by a single write operation. fs.eb_usage[eb_id].e_type = eb_type; return; } /* tell gcinfo that we wrote an erase block of a specific type */ unsigned int write_time = gcinfo_update_writetime(fs, eb_type); // Update the meta data of the erase block that was written to. fs.eb_usage[eb_id].e_type = eb_type; fs.eb_usage[eb_id].e_lastwrite = put_be16(write_time); eb_inc_cvalid(fs, eb_id); inc_be16(fs.eb_usage[eb_id].e_writeops); int max_writeops = fs.erasesize / fs.clustersize; uint16_t writeops = get_be16(fs.eb_usage[eb_id].e_writeops); if (!summary_required(fs, eb_type)) { if (writeops == max_writeops) { // An erase block without summary is implicitly // finalized when its maximum write operations count // is reached. gcinfo_inc_writecnt(fs, eb_type); } return; } // The erase block still needs a summary if it was just opened. summary* eb_summary; if (writeops == 1) { // Create a new erase block summary buffer for the newly // opened erase block and add it to the summary list. eb_summary = summary_open(*fs.summary_cache, eb_type); } else { // The summary for this erase block should already exist. eb_summary = summary_get(*fs.summary_cache, eb_type); } // The last cluster of a cluster indirect erase block contains the // inode ids of all inodes that have data inside this erase block. summary_add_ref(eb_summary, writeops - 1, get_be32(ino_no)); // The summary information of every open erase block is cached. // It will be written to the end of the erase block when this is full. if (writeops == (max_writeops - 1)) { // The last write operation filled the erase block. // Write its summary to finalize it. summary_write(fs, eb_summary, eb_id); summary_close(*fs.summary_cache, eb_summary); /* we just performed another write operation; * tell gcinfo and update the erase block's usage data */ write_time = gcinfo_update_writetime(fs, eb_type); fs.eb_usage[eb_id].e_lastwrite = put_be16(write_time); inc_be16(fs.eb_usage[eb_id].e_writeops); gcinfo_inc_writecnt(fs, eb_type); } }