block_id_type block_header::id()const { // Do not include signed_block_header attributes in id, specifically exclude producer_signature. block_id_type result = digest(); //fc::sha256::hash(*static_cast<const block_header*>(this)); result._hash[0] &= 0xffffffff00000000; result._hash[0] += fc::endian_reverse_u32(block_num()); // store the block num in the ID, 160 bits is plenty for the hash return result; }
block_id_type signed_block_header::id()const { auto tmp = fc::sha224::hash( *this ); tmp._hash[0] = fc::endian_reverse_u32(block_num()); // store the block num in the ID, 160 bits is plenty for the hash static_assert( sizeof(tmp._hash[0]) == 4, "should be 4 bytes" ); block_id_type result; memcpy(result._hash, tmp._hash, std::min(sizeof(result), sizeof(tmp))); return result; }
bool BlockDistributer::get_file( sptr<FileMeta> file , sptr<ClientSession> client , uptr<MessageRequestGet> msg ) { if ( file == nullptr || client == nullptr || msg == nullptr ) return false; auto blocks = file->blocks( ); //sptr<RequestTokenCollection> token = // RequestTokenTable::instance( )->create( sptr<ClusterSession>( client ) , // msg->request_id( ) , // blocks.size( ) ); for ( auto & block : blocks ) { auto nodes = block->nodes( ); size_t min_block_node_id = MAX_SIZE_T; sptr<NodeSession> node_session = nullptr; sptr<NodeMeta> node_meta = nullptr; for ( auto & node : nodes ) { auto n = NodeManager::instance( )->find_node( [node] ( sptr<NodeSession> ns ) { return ns->id( ) == node->node_id( ); } ); if ( n != nullptr ) { if ( n->block_num( ) <= min_block_node_id ) { min_block_node_id = n->id( ); node_session = n; node_meta = node; } } } if ( node_meta == nullptr ) { return false; } uptr<MessageRequestGetToken> req = make_uptr( MessageRequestGetToken ); req->set_index( node_meta->index( ) ); req->set_request_id( msg->request_id( ) ); req->set_block_id( block->id( ) ); req->set_client_id( client->id( ) ); node_session->send_message( move_ptr( req ) ); } client->token_num( blocks.size( ) ); return true; }
static void *alloc_block(struct k_mem_pool *p, int l, size_t lsz) { sys_dnode_t *block; int key = irq_lock(); block = sys_dlist_get(&p->levels[l].free_list); if (block) { clear_free_bit(p, l, block_num(p, block, lsz)); } irq_unlock(key); return block; }
/* Given a position in the user data, return the offset in the DB file */ static tee_fs_off_t pos_to_raw(tee_fs_off_t pos) { tee_fs_off_t res; if (pos < 0) return -1; res = meta_size() + block_num(pos) * block_size_raw(); if (pos % BLOCK_SIZE) { res += block_header_size(); res += pos % BLOCK_SIZE; } return res; }
/** * Given the hash of the requested data, fetch the body. */ virtual message get_item(const item_id& id) override { try { // ilog("Request for item ${id}", ("id", id)); if( id.item_type == graphene::net::block_message_type ) { auto opt_block = _chain_db->fetch_block_by_id(id.item_hash); if( !opt_block ) elog("Couldn't find block ${id} -- corresponding ID in our chain is ${id2}", ("id", id.item_hash)("id2", _chain_db->get_block_id_for_num(block_header::num_from_id(id.item_hash)))); FC_ASSERT( opt_block.valid() ); ilog("Serving up block #${num}", ("num", opt_block->block_num())); return block_message(std::move(*opt_block)); } return trx_message( _chain_db->get_recent_transaction( id.item_hash ) ); } FC_CAPTURE_AND_RETHROW( (id) ) }
/* Takes a block of a given level, splits it into four blocks of the * next smaller level, puts three into the free list as in * free_block() but without the need to check adjacent bits or * recombine, and returns the remaining smaller block. */ static void *break_block(struct k_mem_pool *p, void *block, int l, size_t *lsizes) { int i, bn, key; key = irq_lock(); bn = block_num(p, block, lsizes[l]); for (i = 1; i < 4; i++) { int lbn = 4*bn + i; int lsz = lsizes[l + 1]; void *block2 = (lsz * i) + (char *)block; set_free_bit(p, l + 1, lbn); if (block_fits(p, block2, lsz)) { sys_dlist_append(&p->levels[l + 1].free_list, block2); } } irq_unlock(key); return block; }
static int pool_alloc(struct k_mem_pool *p, struct k_mem_block *block, size_t size) { size_t lsizes[p->n_levels]; int i, alloc_l = -1, free_l = -1, from_l; void *blk = NULL; /* Walk down through levels, finding the one from which we * want to allocate and the smallest one with a free entry * from which we can split an allocation if needed. Along the * way, we populate an array of sizes for each level so we * don't need to waste RAM storing it. */ lsizes[0] = _ALIGN4(p->max_sz); for (i = 0; i < p->n_levels; i++) { if (i > 0) { lsizes[i] = _ALIGN4(lsizes[i-1] / 4); } if (lsizes[i] < size) { break; } alloc_l = i; if (!level_empty(p, i)) { free_l = i; } } if (alloc_l < 0 || free_l < 0) { block->data = NULL; return -ENOMEM; } /* Iteratively break the smallest enclosing block... */ blk = alloc_block(p, free_l, lsizes[free_l]); if (!blk) { /* This can happen if we race with another allocator. * It's OK, just back out and the timeout code will * retry. Note mild overloading: -EAGAIN isn't for * propagation to the caller, it's to tell the loop in * k_mem_pool_alloc() to try again synchronously. But * it means exactly what it says. */ return -EAGAIN; } for (from_l = free_l; level_empty(p, alloc_l) && from_l < alloc_l; from_l++) { blk = break_block(p, blk, from_l, lsizes); } /* ... until we have something to return */ block->data = blk; block->id.pool = pool_id(p); block->id.level = alloc_l; block->id.block = block_num(p, block->data, lsizes[alloc_l]); return 0; }
bool SrmDevice::download( const QDir &tmpdir, QList<DeviceDownloadFile> &files, QString &err) { srmio_error_t serr; struct _srmio_pc_xfer_block_t block; srmio_data_t data( NULL ); srmio_data_t *splitList( NULL ); srmio_data_t *split; int mfirst( -1 ); size_t block_cnt, block_num( 0 ); size_t prog_sum( 0 ), prog_prev( 0 ); size_t chunks_done( 0 ); srmio_time_t splitGap( 72000 ); // 2h - NOTE: we could make this configurable if( ! is_open ){ if( ! open( err ) ) return false; } // fetch preview in case user didn't if( srmio_pc_can_preview(pc) && rideList.size() == 0 ){ if( ! preview( err ) ) return false; } data = srmio_data_new( &serr ); if( ! data ){ err = tr("failed to allocate data handle: %1") .arg(serr.message); goto fail; } if( m_Cancelled ){ err = tr("download cancelled"); goto fail; } if( ! srmio_pc_xfer_start( pc, &serr )){ err = tr("failed to start download: %1") .arg(serr.message); goto fail; } if( ! srmio_pc_xfer_get_blocks( pc, &block_cnt, &serr ) ){ err = tr("failed to get number of data blocks: %1") .arg(serr.message); goto fail1; } for( int i = 0; i < rideList.size(); ++i ){ if( rideList.at(i)->wanted ) prog_sum += rideList.at(i)->work; } while( srmio_pc_xfer_block_next( pc, &block )){ bool wanted = false; struct _srmio_chunk_t chunk; bool is_int; bool is_first; size_t prog_total; if( rideList.empty() ){ wanted = true; } else { for( int i = 0; i < rideList.size(); ++i ){ if( rideList.at(i)->startTime.toTime_t() == block.start / 10 ){ wanted = rideList.at(i)->wanted; break; } } } if( ! wanted ){ emit updateStatus(tr("skipping unselected ride block %1") .arg(block_num +1)); ++block_num; continue; } data->slope = block.slope; data->zeropos = block.zeropos; data->circum = block.circum; if( block.athlete ){ if( data->athlete ) free( data->athlete ); data->athlete = strdup( block.athlete ); } if( ! rideList.empty() ){ prog_total = prog_sum; } else if( block_cnt == 1 ){ prog_total = block.total; } else { prog_total = block_cnt * 1000; } while( srmio_pc_xfer_chunk_next( pc, &chunk, &is_int, &is_first ) ){ if( m_Cancelled ){ err = tr("download cancelled"); goto fail1; } if( chunks_done % 16 == 0 ){ size_t block_done; srmio_pc_xfer_block_progress( pc, &block_done ); if( ! rideList.empty() ){ block_done += prog_prev; } else if( block_cnt == 1 ){ // unchanged } else { block_done = (double)block_num * 1000 + 1000 * block.total / block_done; } emit updateProgress( tr("progress: %1/%2") .arg(block_done) .arg(prog_total)); } if( ! srmio_data_add_chunk( data, &chunk, &serr ) ){ err = tr("adding chunk failed: %1") .arg(serr.message); goto fail1; } ++chunks_done; /* finish previous marker */ if( mfirst >= 0 && ( ! is_int || is_first ) ) if( ! srmio_data_add_marker( data, mfirst, data->cused -2, &serr ) ){ err = tr("adding marker failed: %1") .arg(serr.message); goto fail1; } /* start marker */ if( is_first ){ mfirst = (int)data->cused -1; } else if( ! is_int ){ mfirst = -1; } } /* finalize marker at block end */ if( mfirst >= 0 ){ if( ! srmio_data_add_marker( data, mfirst, data->cused -1, &serr ) ){; err = tr("adding marker failed: %1") .arg(serr.message); goto fail1; } mfirst = -1; } if( ! rideList.empty() ) prog_prev += block.total; else prog_prev += 1000; if( block.athlete ) free( block.athlete ); block.athlete = NULL; ++block_num; } if( srmio_pc_xfer_state_success != srmio_pc_xfer_status( pc, &serr ) ){ err = tr( "download failed: %1") .arg(serr.message); goto fail; } if( ! srmio_pc_xfer_finish( pc, &serr ) ){ err = tr( "download failed: %1") .arg(serr.message); goto fail; } emit updateStatus( tr("got %1 records").arg(data->cused) ); if( m_Cancelled ){ err = tr("download cancelled"); goto fail; } if( ! data->cused ){ err = tr("no data available"); goto fail; } splitList = srmio_data_split( data, splitGap, 1000, &serr ); if( ! splitList ){ err = tr("Couldn't split data: %1") .arg(serr.message); goto fail; } for( split = splitList; *split; ++split ){ FILE *fh( NULL ); srmio_time_t stime; srmio_data_t fixed; DeviceDownloadFile file; // skip empty hunks ... shouldn't happen, just to be safe if( ! (*split)->cused ){ continue; } fixed = srmio_data_fixup( *split, &serr ); if( ! fixed ){ err = tr("Couldn't fixup data: %1") .arg(serr.message); goto fail; } // skip empty hunks ... shouldn't happen, just to be safe if( ! fixed->cused ){ srmio_data_free(fixed); continue; } file.extension = "srm"; if (!get_tmpname(tmpdir, file.name, err)) goto fail; if( ! srmio_data_time_start( fixed, &stime, &serr ) ){ srmio_data_free(fixed); err = tr("Couldn't get start time of data: %1") .arg(serr.message); goto fail; } file.startTime.setTime_t( 0.1 * stime ); fh = fopen( file.name.toAscii().constData(), "wb" ); if( ! fh ){ srmio_data_free(fixed); err = tr( "failed to open file %1: %2") .arg(file.name) .arg(strerror(errno)); goto fail; } if( ! srmio_file_srm7_write(fixed, fh, &serr) ){ srmio_data_free(fixed); err = tr("Couldn't write to file %1: %2") .arg(file.name) .arg(serr.message); fclose(fh); goto fail; } files.append(file); fclose( fh ); srmio_data_free(fixed); } for( split = splitList; *split; ++split ) srmio_data_free( *split ); free(splitList); srmio_data_free( data ); return true; fail1: srmio_pc_xfer_finish(pc, NULL); fail: if( data ) srmio_data_free( data ); if( splitList ){ for( split = splitList; *split; ++split ) srmio_data_free( *split ); free(splitList); } close(); return false; }
static int sql_fs_write(TEE_Result *errno, int fd, const void *buf, size_t len) { struct sql_fs_fd *fdp; size_t remain_bytes = len; const uint8_t *data_ptr = buf; int start_block_num; int end_block_num; int res = -1; int ret; DMSG("(fd: %d, buf: %p, len: %zu)...", fd, (void *)buf, len); mutex_lock(&sql_fs_mutex); *errno = TEE_ERROR_GENERIC; fdp = handle_lookup(&fs_db, fd); if (!fdp) { *errno = TEE_ERROR_BAD_PARAMETERS; goto exit_ret; } if (!len) { res = 0; goto exit_ret; } if (!buf) { *errno = TEE_ERROR_BAD_PARAMETERS; goto exit_ret; } if (fdp->flags & TEE_FS_O_RDONLY) { *errno = TEE_ERROR_ACCESS_CONFLICT; goto exit_ret; } sql_fs_begin_transaction_rpc(); if (fdp->meta.length < (size_t)fdp->pos) { /* Fill hole */ res = sql_fs_ftruncate_internal(errno, fd, fdp->pos); if (res < 0) goto exit; } start_block_num = block_num(fdp->pos); end_block_num = block_num(fdp->pos + len - 1); while (start_block_num <= end_block_num) { tee_fs_off_t offset = fdp->pos % BLOCK_SIZE; size_t size_to_write = MIN(remain_bytes, (size_t)BLOCK_SIZE); if (size_to_write + offset > BLOCK_SIZE) size_to_write = BLOCK_SIZE - offset; res = write_block_partial(errno, fdp, start_block_num, data_ptr, size_to_write, offset); if (res < 0) goto exit; data_ptr += size_to_write; remain_bytes -= size_to_write; fdp->pos += size_to_write; start_block_num++; } fdp->meta.length = fdp->pos; res = write_meta(errno, fdp); exit: sql_fs_end_transaction_rpc(res < 0); exit_ret: mutex_unlock(&sql_fs_mutex); ret = (res < 0) ? res : (int)len; DMSG("...%d", ret); return ret; }
static int sql_fs_read(TEE_Result *errno, int fd, void *buf, size_t len) { struct sql_fs_fd *fdp; size_t remain_bytes = len; uint8_t *data_ptr = buf; uint8_t *block = NULL; int start_block_num; int end_block_num; int res = -1; int ret; DMSG("(fd: %d, buf: %p, len: %zu)...", fd, (void *)buf, len); mutex_lock(&sql_fs_mutex); *errno = TEE_ERROR_GENERIC; fdp = handle_lookup(&fs_db, fd); if (!fdp) { *errno = TEE_ERROR_BAD_PARAMETERS; goto exit_ret; } if ((fdp->pos + len) < len || fdp->pos > (tee_fs_off_t)fdp->meta.length) len = 0; else if (fdp->pos + len > fdp->meta.length) len = fdp->meta.length - fdp->pos; if (!len) { res = 0; goto exit_ret; } if (!buf) { *errno = TEE_ERROR_BAD_PARAMETERS; goto exit_ret; } if (fdp->flags & TEE_FS_O_WRONLY) { *errno = TEE_ERROR_ACCESS_CONFLICT; goto exit_ret; } start_block_num = block_num(fdp->pos); end_block_num = block_num(fdp->pos + len - 1); block = malloc(BLOCK_SIZE); if (!block) { *errno = TEE_ERROR_OUT_OF_MEMORY; goto exit_ret; } sql_fs_begin_transaction_rpc(); while (start_block_num <= end_block_num) { tee_fs_off_t offset = fdp->pos % BLOCK_SIZE; size_t size_to_read = MIN(remain_bytes, (size_t)BLOCK_SIZE); if (size_to_read + offset > BLOCK_SIZE) size_to_read = BLOCK_SIZE - offset; /* * REVISIT: implement read_block_partial() since we have * write_block_partial()? */ res = read_block(errno, fdp, start_block_num, block); if (res < 0) goto exit; memcpy(data_ptr, block + offset, size_to_read); data_ptr += size_to_read; remain_bytes -= size_to_read; fdp->pos += size_to_read; start_block_num++; } res = 0; exit: sql_fs_end_transaction_rpc(res < 0); free(block); exit_ret: mutex_unlock(&sql_fs_mutex); ret = (res < 0) ? res : (int)len; DMSG("...%d", ret); return ret; }
static int sql_fs_ftruncate_internal(TEE_Result *errno, int fd, tee_fs_off_t new_length) { struct sql_fs_fd *fdp; tee_fs_off_t old_length; int rc = -1; DMSG("(fd: %d, new_length: %" PRId64 ")...", fd, new_length); *errno = TEE_ERROR_GENERIC; fdp = handle_lookup(&fs_db, fd); if (!fdp) { *errno = TEE_ERROR_BAD_PARAMETERS; goto exit_ret; } old_length = (tee_fs_off_t)fdp->meta.length; if (new_length == old_length) { rc = 0; goto exit_ret; } sql_fs_begin_transaction_rpc(); if (new_length < old_length) { /* Trim unused blocks */ int old_last_block = block_num(old_length); int last_block = block_num(new_length); tee_fs_off_t off; if (last_block < old_last_block) { off = block_pos_raw(last_block); rc = tee_fs_rpc_ftruncate(OPTEE_MSG_RPC_CMD_SQL_FS, fd, off); if (rc < 0) goto exit; } } else { /* Extend file with zeroes */ tee_fs_off_t off = old_length % BLOCK_SIZE; size_t bnum = block_num(old_length); size_t end_bnum = block_num(new_length); while (bnum <= end_bnum) { size_t len = (size_t)BLOCK_SIZE - (size_t)off; rc = write_block_partial(errno, fdp, bnum, NULL, len, off); if (rc < 0) goto exit; off = 0; bnum++; } } fdp->meta.length = new_length; rc = write_meta(errno, fdp); exit: sql_fs_end_transaction_rpc(rc < 0); exit_ret: DMSG("...%d", rc); return rc; }