cregit-Linux how code gets into the kernel

Release 4.11 drivers/target/iscsi/iscsi_target_datain_values.c

/*******************************************************************************
 * This file contains the iSCSI Target DataIN value generation functions.
 *
 * (c) Copyright 2007-2013 Datera, Inc.
 *
 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 ******************************************************************************/

#include <linux/slab.h>
#include <scsi/iscsi_proto.h>
#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_seq_pdu_list.h"
#include "iscsi_target_erl1.h"
#include "iscsi_target_util.h"
#include "iscsi_target.h"
#include "iscsi_target_datain_values.h"


struct iscsi_datain_req *iscsit_allocate_datain_req(void) { struct iscsi_datain_req *dr; dr = kmem_cache_zalloc(lio_dr_cache, GFP_ATOMIC); if (!dr) { pr_err("Unable to allocate memory for" " struct iscsi_datain_req\n"); return NULL; } INIT_LIST_HEAD(&dr->cmd_datain_node); return dr; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger4998.00%150.00%
Andy Grover12.00%150.00%
Total50100.00%2100.00%


void iscsit_attach_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr) { spin_lock(&cmd->datain_lock); list_add_tail(&dr->cmd_datain_node, &cmd->datain_list); spin_unlock(&cmd->datain_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger4397.73%150.00%
Andy Grover12.27%150.00%
Total44100.00%2100.00%


void iscsit_free_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr) { spin_lock(&cmd->datain_lock); list_del(&dr->cmd_datain_node); spin_unlock(&cmd->datain_lock); kmem_cache_free(lio_dr_cache, dr); }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger4597.83%150.00%
Andy Grover12.17%150.00%
Total46100.00%2100.00%


void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd) { struct iscsi_datain_req *dr, *dr_tmp; spin_lock(&cmd->datain_lock); list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, cmd_datain_node) { list_del(&dr->cmd_datain_node); kmem_cache_free(lio_dr_cache, dr); } spin_unlock(&cmd->datain_lock); }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger5996.72%150.00%
Andy Grover23.28%150.00%
Total61100.00%2100.00%


struct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *cmd) { if (list_empty(&cmd->datain_list)) { pr_err("cmd->datain_list is empty for ITT:" " 0x%08x\n", cmd->init_task_tag); return NULL; } return list_first_entry(&cmd->datain_list, struct iscsi_datain_req, cmd_datain_node); }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger4282.35%150.00%
Andy Grover917.65%150.00%
Total51100.00%2100.00%

/* * For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=Yes. */
static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes( struct iscsi_cmd *cmd, struct iscsi_datain *datain) { u32 next_burst_len, read_data_done, read_data_left; struct iscsi_conn *conn = cmd->conn; struct iscsi_datain_req *dr; dr = iscsit_get_datain_req(cmd); if (!dr) return NULL; if (dr->recovery && dr->generate_recovery_values) { if (iscsit_create_recovery_datain_values_datasequenceinorder_yes( cmd, dr) < 0) return NULL; dr->generate_recovery_values = 0; } next_burst_len = (!dr->recovery) ? cmd->next_burst_len : dr->next_burst_len; read_data_done = (!dr->recovery) ? cmd->read_data_done : dr->read_data_done; read_data_left = (cmd->se_cmd.data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); return NULL; } if ((read_data_left <= conn->conn_ops->MaxRecvDataSegmentLength) && (read_data_left <= (conn->sess->sess_ops->MaxBurstLength - next_burst_len))) { datain->length = read_data_left; datain->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS); if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) datain->flags |= ISCSI_FLAG_DATA_ACK; } else { if ((next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) < conn->sess->sess_ops->MaxBurstLength) { datain->length = conn->conn_ops->MaxRecvDataSegmentLength; next_burst_len += datain->length; } else { datain->length = (conn->sess->sess_ops->MaxBurstLength - next_burst_len); next_burst_len = 0; datain->flags |= ISCSI_FLAG_CMD_FINAL; if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) datain->flags |= ISCSI_FLAG_DATA_ACK; } } datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; datain->offset = read_data_done; if (!dr->recovery) { cmd->next_burst_len = next_burst_len; cmd->read_data_done += datain->length; } else { dr->next_burst_len = next_burst_len; dr->read_data_done += datain->length; } if (!dr->recovery) { if (datain->flags & ISCSI_FLAG_DATA_STATUS) dr->dr_complete = DATAIN_COMPLETE_NORMAL; return dr; } if (!dr->runlength) { if (datain->flags & ISCSI_FLAG_DATA_STATUS) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } else { if ((dr->begrun + dr->runlength) == dr->data_sn) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } return dr; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger46999.58%150.00%
Andy Grover20.42%150.00%
Total471100.00%2100.00%

/* * For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=Yes. */
static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes( struct iscsi_cmd *cmd, struct iscsi_datain *datain) { u32 offset, read_data_done, read_data_left, seq_send_order; struct iscsi_conn *conn = cmd->conn; struct iscsi_datain_req *dr; struct iscsi_seq *seq; dr = iscsit_get_datain_req(cmd); if (!dr) return NULL; if (dr->recovery && dr->generate_recovery_values) { if (iscsit_create_recovery_datain_values_datasequenceinorder_no( cmd, dr) < 0) return NULL; dr->generate_recovery_values = 0; } read_data_done = (!dr->recovery) ? cmd->read_data_done : dr->read_data_done; seq_send_order = (!dr->recovery) ? cmd->seq_send_order : dr->seq_send_order; read_data_left = (cmd->se_cmd.data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); return NULL; } seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order); if (!seq) return NULL; seq->sent = 1; if (!dr->recovery && !seq->next_burst_len) seq->first_datasn = cmd->data_sn; offset = (seq->offset + seq->next_burst_len); if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= cmd->se_cmd.data_length) { datain->length = (cmd->se_cmd.data_length - offset); datain->offset = offset; datain->flags |= ISCSI_FLAG_CMD_FINAL; if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) datain->flags |= ISCSI_FLAG_DATA_ACK; seq->next_burst_len = 0; seq_send_order++; } else { if ((seq->next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) < conn->sess->sess_ops->MaxBurstLength) { datain->length = conn->conn_ops->MaxRecvDataSegmentLength; datain->offset = (seq->offset + seq->next_burst_len); seq->next_burst_len += datain->length; } else { datain->length = (conn->sess->sess_ops->MaxBurstLength - seq->next_burst_len); datain->offset = (seq->offset + seq->next_burst_len); datain->flags |= ISCSI_FLAG_CMD_FINAL; if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) datain->flags |= ISCSI_FLAG_DATA_ACK; seq->next_burst_len = 0; seq_send_order++; } } if ((read_data_done + datain->length) == cmd->se_cmd.data_length) datain->flags |= ISCSI_FLAG_DATA_STATUS; datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; if (!dr->recovery) { cmd->seq_send_order = seq_send_order; cmd->read_data_done += datain->length; } else { dr->seq_send_order = seq_send_order; dr->read_data_done += datain->length; } if (!dr->recovery) { if (datain->flags & ISCSI_FLAG_CMD_FINAL) seq->last_datasn = datain->data_sn; if (datain->flags & ISCSI_FLAG_DATA_STATUS) dr->dr_complete = DATAIN_COMPLETE_NORMAL; return dr; } if (!dr->runlength) { if (datain->flags & ISCSI_FLAG_DATA_STATUS) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } else { if ((dr->begrun + dr->runlength) == dr->data_sn) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } return dr; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger60598.69%150.00%
Andy Grover81.31%150.00%
Total613100.00%2100.00%

/* * For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=No. */
static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no( struct iscsi_cmd *cmd, struct iscsi_datain *datain) { u32 next_burst_len, read_data_done, read_data_left; struct iscsi_conn *conn = cmd->conn; struct iscsi_datain_req *dr; struct iscsi_pdu *pdu; dr = iscsit_get_datain_req(cmd); if (!dr) return NULL; if (dr->recovery && dr->generate_recovery_values) { if (iscsit_create_recovery_datain_values_datasequenceinorder_yes( cmd, dr) < 0) return NULL; dr->generate_recovery_values = 0; } next_burst_len = (!dr->recovery) ? cmd->next_burst_len : dr->next_burst_len; read_data_done = (!dr->recovery) ? cmd->read_data_done : dr->read_data_done; read_data_left = (cmd->se_cmd.data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); return dr; } pdu = iscsit_get_pdu_holder_for_seq(cmd, NULL); if (!pdu) return dr; if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) { pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS); if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) pdu->flags |= ISCSI_FLAG_DATA_ACK; next_burst_len = 0; } else { if ((next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) < conn->sess->sess_ops->MaxBurstLength) next_burst_len += pdu->length; else { pdu->flags |= ISCSI_FLAG_CMD_FINAL; if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) pdu->flags |= ISCSI_FLAG_DATA_ACK; next_burst_len = 0; } } pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; if (!dr->recovery) { cmd->next_burst_len = next_burst_len; cmd->read_data_done += pdu->length; } else { dr->next_burst_len = next_burst_len; dr->read_data_done += pdu->length; } datain->flags = pdu->flags; datain->length = pdu->length; datain->offset = pdu->offset; datain->data_sn = pdu->data_sn; if (!dr->recovery) { if (datain->flags & ISCSI_FLAG_DATA_STATUS) dr->dr_complete = DATAIN_COMPLETE_NORMAL; return dr; } if (!dr->runlength) { if (datain->flags & ISCSI_FLAG_DATA_STATUS) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } else { if ((dr->begrun + dr->runlength) == dr->data_sn) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } return dr; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger47399.16%150.00%
Andy Grover40.84%150.00%
Total477100.00%2100.00%

/* * For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=No. */
static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no( struct iscsi_cmd *cmd, struct iscsi_datain *datain) { u32 read_data_done, read_data_left, seq_send_order; struct iscsi_conn *conn = cmd->conn; struct iscsi_datain_req *dr; struct iscsi_pdu *pdu; struct iscsi_seq *seq = NULL; dr = iscsit_get_datain_req(cmd); if (!dr) return NULL; if (dr->recovery && dr->generate_recovery_values) { if (iscsit_create_recovery_datain_values_datasequenceinorder_no( cmd, dr) < 0) return NULL; dr->generate_recovery_values = 0; } read_data_done = (!dr->recovery) ? cmd->read_data_done : dr->read_data_done; seq_send_order = (!dr->recovery) ? cmd->seq_send_order : dr->seq_send_order; read_data_left = (cmd->se_cmd.data_length - read_data_done); if (!read_data_left) { pr_err("ITT: 0x%08x read_data_left is zero!\n", cmd->init_task_tag); return NULL; } seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order); if (!seq) return NULL; seq->sent = 1; if (!dr->recovery && !seq->next_burst_len) seq->first_datasn = cmd->data_sn; pdu = iscsit_get_pdu_holder_for_seq(cmd, seq); if (!pdu) return NULL; if (seq->pdu_send_order == seq->pdu_count) { pdu->flags |= ISCSI_FLAG_CMD_FINAL; if (conn->sess->sess_ops->ErrorRecoveryLevel > 0) pdu->flags |= ISCSI_FLAG_DATA_ACK; seq->next_burst_len = 0; seq_send_order++; } else seq->next_burst_len += pdu->length; if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) pdu->flags |= ISCSI_FLAG_DATA_STATUS; pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++; if (!dr->recovery) { cmd->seq_send_order = seq_send_order; cmd->read_data_done += pdu->length; } else { dr->seq_send_order = seq_send_order; dr->read_data_done += pdu->length; } datain->flags = pdu->flags; datain->length = pdu->length; datain->offset = pdu->offset; datain->data_sn = pdu->data_sn; if (!dr->recovery) { if (datain->flags & ISCSI_FLAG_CMD_FINAL) seq->last_datasn = datain->data_sn; if (datain->flags & ISCSI_FLAG_DATA_STATUS) dr->dr_complete = DATAIN_COMPLETE_NORMAL; return dr; } if (!dr->runlength) { if (datain->flags & ISCSI_FLAG_DATA_STATUS) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } else { if ((dr->begrun + dr->runlength) == dr->data_sn) { dr->dr_complete = (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ? DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY : DATAIN_COMPLETE_CONNECTION_RECOVERY; } } return dr; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger50599.21%150.00%
Andy Grover40.79%150.00%
Total509100.00%2100.00%


struct iscsi_datain_req *iscsit_get_datain_values( struct iscsi_cmd *cmd, struct iscsi_datain *datain) { struct iscsi_conn *conn = cmd->conn; if (conn->sess->sess_ops->DataSequenceInOrder && conn->sess->sess_ops->DataPDUInOrder) return iscsit_set_datain_values_yes_and_yes(cmd, datain); else if (!conn->sess->sess_ops->DataSequenceInOrder && conn->sess->sess_ops->DataPDUInOrder) return iscsit_set_datain_values_no_and_yes(cmd, datain); else if (conn->sess->sess_ops->DataSequenceInOrder && !conn->sess->sess_ops->DataPDUInOrder) return iscsit_set_datain_values_yes_and_no(cmd, datain); else if (!conn->sess->sess_ops->DataSequenceInOrder && !conn->sess->sess_ops->DataPDUInOrder) return iscsit_set_datain_values_no_and_no(cmd, datain); return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger140100.00%1100.00%
Total140100.00%1100.00%

EXPORT_SYMBOL(iscsit_get_datain_values);

Overall Contributors

PersonTokensPropCommitsCommitProp
Nicholas Bellinger245598.36%228.57%
Andy Grover321.28%228.57%
Varun Prakash50.20%114.29%
Bart Van Assche30.12%114.29%
Sagi Grimberg10.04%114.29%
Total2496100.00%7100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.