示例#1
0
 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;
 }
示例#2
0
文件: block.cpp 项目: AlexChien/steem
 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;
 }
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
/* 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;
}
示例#6
0
 /**
  * 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) ) }
示例#7
0
/* 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;
}
示例#8
0
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;
}
示例#9
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;
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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;
}