Ejemplo n.º 1
0
// come back with a fin response
pack_and_data_t *process_client_fin(pack_and_data_t *pin) {
    packet_head_t *fin_pkt = pin->ph;
    uint32_t cid = fin_pkt->card_id;
    uint32_t acd =  fin_pkt->auth_code;
    uint32_t txn_id = fin_pkt->transaction_id;
    account_entry_t * ae = get_account(cid, acd);

    if(ae == NULL) {
        ERRNO = ERRNO_MP_NOT_FOUND;
        return NULL;
    }

    txn_entry_t * te = get_transaction(ae, txn_id);
    if(te == NULL) {
        // err no set by get_txn
        return NULL;
    }


    if(finalize_transaction(te) != OK) {
        // finalize transaction sets huge errno for double fin
        return NULL;
    }



    return create_basic_response(cid, acd, txn_id, FIN, fin_pkt->op_code, OK, 0);

}
Ejemplo n.º 2
0
acct_txn_entry_t * get_acct_txn_reg(uint32_t cid, uint32_t acd, uint32_t txn_id) {

    account_entry_t * ae = get_account(cid, acd);



    if(ae == NULL) {
        ERRNO = ERRNO_MP_NOT_FOUND;
        return NULL;
    }

    txn_entry_t * te = get_transaction(ae, txn_id);
    if(te == NULL) {
        ERRNO = ERRNO_MP_NOT_FOUND;
        return NULL;
    }

    acct_txn_entry_t *aet = (acct_txn_entry_t *) malloc(sizeof(acct_txn_entry_t));
    if(aet == NULL) {
        ERRNO = ERRNO_MP_ALLOC;
        return NULL;
    }
    aet->ae = ae;
    aet->txn = te;

    return aet;


};
Ejemplo n.º 3
0
// set last message, from transaction or default if none specified. msg_index is used for error reporting only
void DialogState::setLastReceivedMessage(const string &msg, const string &name, int msg_index)
{
  DEBUG_IN("name = '%s' Message Length = %d", name.c_str(), msg.length());

  // set default transactions's last message
  {
    TransactionState &txn = get_transaction("", msg_index);
    txn.setLastReceivedMessage(msg);
  }

  // set per-transaction message
  if (!name.empty()) {
    TransactionState &txn = get_transaction(name, msg_index);
    txn.setLastReceivedMessage(msg);
    DEBUG("Set last message for transaction %s", name.c_str());
  }
}
Ejemplo n.º 4
0
bool leveldb_common::duplicate_exists(const hash_digest& tx_hash,
    uint32_t block_height, uint32_t tx_index)
{
    leveldb_tx_info tx;
    if (!get_transaction(tx, tx_hash, false, false))
        return false;
    BITCOIN_ASSERT(block_height == 91842 || block_height == 91880);
    return true;
}
Ejemplo n.º 5
0
pack_and_data_t * process_client_refund_op(pack_and_data_t * pin) {
    packet_head_t *rf_pkt = pin->ph;
    packet_data_refund_t *rcd = pin->data;
    uint32_t cid = rf_pkt->card_id;
    uint32_t acd = rf_pkt->auth_code;
    uint32_t txn_id = rf_pkt->transaction_id;


    acct_txn_entry_t * aet = get_acct_txn_reg(cid, acd, txn_id);



    if(aet == NULL) {
        return NULL;
    }


    txn_entry_t * ref_txn = get_transaction(aet->ae, rcd->transaction_id);
    if(ref_txn == NULL) {
        ERRNO = ERRNO_MP_NOT_FOUND;
        return NULL;
    }

    packet_data_purchase_t *log_pur_data = ref_txn->data;

#if PATCHED
    if(log_pur_data == NULL) {
        return NULL;
    }
#endif


    if(log_pur_data->purchase_id != rcd->purchase_id) {


        // the purchase id refund request doesn't match up...

        ERRNO = ERRNO_MP_NOT_FOUND;
        return NULL;
    }

    uint32_t proposed_post_refund = aet->ae->balance + log_pur_data->cost;
    if(proposed_post_refund <= 0xFFFFFFFF && proposed_post_refund >= aet->ae->balance) {
        aet->ae->balance = proposed_post_refund;

    } else {
        ERRNO = ERRNO_MP_REFUND_FULL;
        return NULL;
    }

    add_transaction_log_entry(aet->ae, pin);

    remove_transaction_log_entry(aet->ae,ref_txn);
    free(aet);
    return create_basic_response(cid, acd, txn_id, OPS, REFUND, OK, 0);
}
Ejemplo n.º 6
0
txn_entry_t * add_transaction_log_entry(account_entry_t * ae,  pack_and_data_t *pad){
	// we parse packet header here, again, and dump the whole transaction log into the linked list node

	packet_head_t *ph = pad->ph;
	void *txn_data = pad->data;
	txn_entry_t *le = get_transaction(ae, ph->transaction_id);
	if(le == NULL){

		return NULL;
	}


	if(le->p == NULL)
		le->p = (packet_head_t *) malloc(sizeof(packet_head_t));
	
	if(le->p == NULL)
		return NULL;
	

	



	// copy in original packet header and packet data ...
	cgc_memcpy(le->p, (void *) ph, sizeof(packet_head_t));

	size_t data_sz = pad->pay_data_l;
	le->data_sz = data_sz;


	if(data_sz != 0){
		le->data = malloc(data_sz);
		if(txn_data == NULL)
			return NULL;
		cgc_memcpy(le->data, txn_data, data_sz);	
	}
	
	return le;
}
Ejemplo n.º 7
0
// get last message, from transaction or default if none specified. msg_index is used for error reporting only
const string &DialogState::getLastReceivedMessage(const string &name, int msg_index)
{
  DEBUG_IN("name = %s", name.c_str());
  TransactionState &txn = get_transaction(name, msg_index);
  return txn.getLastReceivedMessage();
}
Ejemplo n.º 8
0
static int start_this_handle(journal_t *journal, handle_t *handle)
{
	transaction_t *transaction;
	int needed;
	int nblocks = handle->h_buffer_credits;
	transaction_t *new_transaction = NULL;
	int ret = 0;

	if (nblocks > journal->j_max_transaction_buffers) {
		printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
		       current->comm, nblocks,
		       journal->j_max_transaction_buffers);
		ret = -ENOSPC;
		goto out;
	}

alloc_transaction:
	if (!journal->j_running_transaction) {
		new_transaction = kzalloc(sizeof(*new_transaction),
						GFP_NOFS|__GFP_NOFAIL);
		if (!new_transaction) {
			ret = -ENOMEM;
			goto out;
		}
	}

	jbd_debug(3, "New handle %p going live.\n", handle);

repeat:

	/*
	 * We need to hold j_state_lock until t_updates has been incremented,
	 * for proper journal barrier handling
	 */
	spin_lock(&journal->j_state_lock);
repeat_locked:
	if (is_journal_aborted(journal) ||
	    (journal->j_errno != 0 && !(journal->j_flags & JFS_ACK_ERR))) {
		spin_unlock(&journal->j_state_lock);
		ret = -EROFS;
		goto out;
	}

	/* Wait on the journal's transaction barrier if necessary */
	if (journal->j_barrier_count) {
		spin_unlock(&journal->j_state_lock);
		wait_event(journal->j_wait_transaction_locked,
				journal->j_barrier_count == 0);
		goto repeat;
	}

	if (!journal->j_running_transaction) {
		if (!new_transaction) {
			spin_unlock(&journal->j_state_lock);
			goto alloc_transaction;
		}
		get_transaction(journal, new_transaction);
		new_transaction = NULL;
	}

	transaction = journal->j_running_transaction;

	/*
	 * If the current transaction is locked down for commit, wait for the
	 * lock to be released.
	 */
	if (transaction->t_state == T_LOCKED) {
		DEFINE_WAIT(wait);

		prepare_to_wait(&journal->j_wait_transaction_locked,
					&wait, TASK_UNINTERRUPTIBLE);
		spin_unlock(&journal->j_state_lock);
		schedule();
		finish_wait(&journal->j_wait_transaction_locked, &wait);
		goto repeat;
	}

	/*
	 * If there is not enough space left in the log to write all potential
	 * buffers requested by this operation, we need to stall pending a log
	 * checkpoint to free some more log space.
	 */
	spin_lock(&transaction->t_handle_lock);
	needed = transaction->t_outstanding_credits + nblocks;

	if (needed > journal->j_max_transaction_buffers) {
		/*
		 * If the current transaction is already too large, then start
		 * to commit it: we can then go back and attach this handle to
		 * a new transaction.
		 */
		DEFINE_WAIT(wait);

		jbd_debug(2, "Handle %p starting new commit...\n", handle);
		spin_unlock(&transaction->t_handle_lock);
		prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
				TASK_UNINTERRUPTIBLE);
		__log_start_commit(journal, transaction->t_tid);
		spin_unlock(&journal->j_state_lock);
		schedule();
		finish_wait(&journal->j_wait_transaction_locked, &wait);
		goto repeat;
	}

	/*
	 * The commit code assumes that it can get enough log space
	 * without forcing a checkpoint.  This is *critical* for
	 * correctness: a checkpoint of a buffer which is also
	 * associated with a committing transaction creates a deadlock,
	 * so commit simply cannot force through checkpoints.
	 *
	 * We must therefore ensure the necessary space in the journal
	 * *before* starting to dirty potentially checkpointed buffers
	 * in the new transaction.
	 *
	 * The worst part is, any transaction currently committing can
	 * reduce the free space arbitrarily.  Be careful to account for
	 * those buffers when checkpointing.
	 */

	/*
	 * @@@ AKPM: This seems rather over-defensive.  We're giving commit
	 * a _lot_ of headroom: 1/4 of the journal plus the size of
	 * the committing transaction.  Really, we only need to give it
	 * committing_transaction->t_outstanding_credits plus "enough" for
	 * the log control blocks.
	 * Also, this test is inconsitent with the matching one in
	 * journal_extend().
	 */
	if (__log_space_left(journal) < jbd_space_needed(journal)) {
		jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
		spin_unlock(&transaction->t_handle_lock);
		__log_wait_for_space(journal);
		goto repeat_locked;
	}

	/* OK, account for the buffers that this operation expects to
	 * use and add the handle to the running transaction. */

	handle->h_transaction = transaction;
	transaction->t_outstanding_credits += nblocks;
	transaction->t_updates++;
	transaction->t_handle_count++;
	jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
		  handle, nblocks, transaction->t_outstanding_credits,
		  __log_space_left(journal));
	spin_unlock(&transaction->t_handle_lock);
	spin_unlock(&journal->j_state_lock);

	lock_map_acquire(&handle->h_lockdep_map);
out:
	if (unlikely(new_transaction))		/* It's usually NULL */
		kfree(new_transaction);
	return ret;
}
Ejemplo n.º 9
0
static int start_this_handle(journal_t *journal, handle_t *handle)
{
	transaction_t *transaction;
	int needed;
	int nblocks = handle->h_buffer_credits;
	
	jfs_debug(4, "New handle %p going live.\n", handle);

repeat:

	lock_journal(journal);

	if ((journal->j_flags & JFS_ABORT) ||
	    (journal->j_errno != 0 && !(journal->j_flags & JFS_ACK_ERR))) {
		unlock_journal(journal);
		return -EROFS; 
	}

	/* Wait on the journal's transaction barrier if necessary */
	if (journal->j_barrier_count) {
		unlock_journal(journal);
		sleep_on(&journal->j_wait_transaction_locked);
		goto repeat;
	}
	
repeat_locked:
	if (!journal->j_running_transaction)
		get_transaction(journal);
	/* @@@ Error? */
	J_ASSERT(journal->j_running_transaction);
	
	transaction = journal->j_running_transaction;

	/* If the current transaction is locked down for commit, wait
	 * for the lock to be released. */

	if (transaction->t_state == T_LOCKED) {
		unlock_journal(journal);
		jfs_debug(3, "Handle %p stalling...\n", handle);
		sleep_on(&journal->j_wait_transaction_locked);
		goto repeat;
	}
	
	/* If there is not enough space left in the log to write all
	 * potential buffers requested by this operation, we need to
	 * stall pending a log checkpoint to free some more log
	 * space. */

	needed = transaction->t_outstanding_credits + nblocks;

	if (needed > journal->j_max_transaction_buffers) {
		/* If the current transaction is already too large, then
		 * start to commit it: we can then go back and attach
		 * this handle to a new transaction. */
		
		jfs_debug(2, "Handle %p starting new commit...\n", handle);
		log_start_commit(journal, transaction);
		unlock_journal(journal);
		sleep_on(&journal->j_wait_transaction_locked);
		lock_journal(journal);
		goto repeat_locked;
	}

	/* 
	 * The commit code assumes that it can get enough log space
	 * without forcing a checkpoint.  This is *critical* for
	 * correctness: a checkpoint of a buffer which is also
	 * associated with a committing transaction creates a deadlock,
	 * so commit simply cannot force through checkpoints.
	 *
	 * We must therefore ensure the necessary space in the journal
	 * *before* starting to dirty potentially checkpointed buffers
	 * in the new transaction. 
	 *
	 * The worst part is, any transaction currently committing can
	 * reduce the free space arbitrarily.  Be careful to account for
	 * those buffers when checkpointing.
	 */

	needed = journal->j_max_transaction_buffers;
	if (journal->j_committing_transaction) 
		needed += journal->j_committing_transaction->t_outstanding_credits;
	
	if (log_space_left(journal) < needed) {
		jfs_debug(2, "Handle %p waiting for checkpoint...\n", handle);
		log_wait_for_space(journal, needed);
		goto repeat_locked;
	}

	/* OK, account for the buffers that this operation expects to
	 * use and add the handle to the running transaction. */

	handle->h_transaction = transaction;
	transaction->t_outstanding_credits += nblocks;
	transaction->t_updates++;
	jfs_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
		  handle, nblocks, transaction->t_outstanding_credits,
		  log_space_left(journal));

	unlock_journal(journal);
	
	return 0;
}