예제 #1
0
파일: pdu.c 프로젝트: vipmike007/libiscsi
int
iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
		   unsigned char *dptr, int dsize)
{
	if (pdu == NULL) {
		iscsi_set_error(iscsi, "trying to add data to NULL pdu");
		return -1;
	}
	if (dsize == 0) {
		iscsi_set_error(iscsi, "Trying to append zero size data to "
				"pdu");
		return -1;
	}

	if (iscsi_add_data(iscsi, &pdu->outdata, dptr, dsize, 1) != 0) {
		iscsi_set_error(iscsi, "failed to add data to pdu buffer");
		return -1;
	}

	/* update data segment length */
	*(uint32_t *)&pdu->outdata.data[4] = htonl(pdu->outdata.size
						   - ISCSI_HEADER_SIZE);

	return 0;
}
예제 #2
0
파일: scsi-command.c 프로젝트: dooglus/ccan
int iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, const unsigned char *hdr, int size, int *is_finished)
{
    int statsn, flags, status;
    struct iscsi_scsi_cbdata *scsi_cbdata = pdu->scsi_cbdata;
    struct scsi_task *task = scsi_cbdata->task;
    int dsl;

    statsn = ntohl(*(uint32_t *)&hdr[24]);
    if (statsn > (int)iscsi->statsn) {
        iscsi->statsn = statsn;
    }

    flags = hdr[1];
    if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
        printf("scsi response asked for ACK 0x%02x\n", flags);
        pdu->callback(iscsi, ISCSI_STATUS_ERROR, task, pdu->private_data);
        return -1;
    }
    /* for now, we ignore all overflow/underflow flags. We just print/log them so we can tweak
     * libiscsi to not generate under/over flows
     */
    if ((flags&ISCSI_PDU_DATA_RESIDUAL_OVERFLOW) != 0) {
        printf("scsi response contains residual overflow 0x%02x\n", flags);
    }
    if ((flags&ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW) != 0) {
        printf("scsi response contains residual underflow 0x%02x\n", flags);
    }

    dsl = ntohl(*(uint32_t *)&hdr[4])&0x00ffffff;

    if (dsl > size - ISCSI_HEADER_SIZE) {
        printf ("dsl is :%d, while buffser size if %d\n", dsl, size - ISCSI_HEADER_SIZE);
    }

    if (iscsi_add_data(&pdu->indata, discard_const(hdr + ISCSI_HEADER_SIZE), dsl, 0) != 0) {
        printf("failed to add data to pdu in buffer\n");
        return -3;
    }


    if ((flags&ISCSI_PDU_DATA_FINAL) == 0) {
        printf("scsi data-in without Final bit: 0x%02x\n", flags);
        *is_finished = 0;
    }
    if ((flags&ISCSI_PDU_DATA_CONTAINS_STATUS) == 0) {
        printf("scsi data-in without Status bit: 0x%02x\n", flags);
        *is_finished = 0;
    }

    if (*is_finished == 0) {
        return 0;
    }


    /* this was the final data-in packet in the sequence and it has the s-bit set, so invoke the
     * callback.
     */
    status = hdr[3];
    task->datain.data = pdu->indata.data;
    task->datain.size = pdu->indata.size;

    pdu->callback(iscsi, status, task, pdu->private_data);

    return 0;
}