Module Name: src
Committed By: mlelstv
Date: Sat Jun 9 06:19:58 UTC 2012
Modified Files:
src/sys/dev/iscsi: iscsi_globals.h iscsi_ioctl.c iscsi_main.c
iscsi_send.c iscsi_text.c iscsi_utils.c
Log Message:
Close file descriptor passed into the kernel on success.
Fix locking of file handle. More cleanup on error paths.
Keep track of CCBs, so they cannot be used after a session ends.
Handle CCB timeouts even when the connection is terminated.
Compute firstdata, firstimmed correctly.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/iscsi/iscsi_globals.h \
src/sys/dev/iscsi/iscsi_text.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/iscsi/iscsi_ioctl.c \
src/sys/dev/iscsi/iscsi_send.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/iscsi/iscsi_main.c
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/iscsi/iscsi_utils.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/iscsi/iscsi_globals.h
diff -u src/sys/dev/iscsi/iscsi_globals.h:1.3 src/sys/dev/iscsi/iscsi_globals.h:1.4
--- src/sys/dev/iscsi/iscsi_globals.h:1.3 Sat Jun 2 16:52:11 2012
+++ src/sys/dev/iscsi/iscsi_globals.h Sat Jun 9 06:19:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_globals.h,v 1.3 2012/06/02 16:52:11 mlelstv Exp $ */
+/* $NetBSD: iscsi_globals.h,v 1.4 2012/06/09 06:19:58 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -387,6 +387,7 @@ struct connection_s {
/* if closing down: status */
int recover; /* recovery count */
/* (reset on first successful data transfer) */
+ int usecount; /* number of active CCBs */
bool destroy; /* conn will be destroyed */
bool in_session;
Index: src/sys/dev/iscsi/iscsi_text.c
diff -u src/sys/dev/iscsi/iscsi_text.c:1.3 src/sys/dev/iscsi/iscsi_text.c:1.4
--- src/sys/dev/iscsi/iscsi_text.c:1.3 Sat Dec 17 20:05:39 2011
+++ src/sys/dev/iscsi/iscsi_text.c Sat Jun 9 06:19:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_text.c,v 1.3 2011/12/17 20:05:39 tls Exp $ */
+/* $NetBSD: iscsi_text.c,v 1.4 2012/06/09 06:19:58 mlelstv Exp $ */
/*-
* Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
@@ -1773,11 +1773,12 @@ set_negotiated_parameters(ccb_t *ccb)
state->FirstBurstLength, state->InitialR2T,
state->ImmediateData));
- conn->max_transfer = min(sess->MaxBurstLength,
- conn->MaxRecvDataSegmentLength);
+ conn->max_transfer = min(sess->MaxBurstLength, conn->MaxRecvDataSegmentLength);
conn->max_firstimmed = (!sess->ImmediateData) ? 0 :
min(sess->FirstBurstLength, conn->max_transfer);
- conn->max_firstdata = (sess->InitialR2T) ? 0 : sess->FirstBurstLength;
+ conn->max_firstdata = (sess->InitialR2T || sess->FirstBurstLength < conn->max_firstimmed) ? 0 :
+ min(sess->FirstBurstLength - conn->max_firstimmed, conn->max_transfer);
+
}
Index: src/sys/dev/iscsi/iscsi_ioctl.c
diff -u src/sys/dev/iscsi/iscsi_ioctl.c:1.2 src/sys/dev/iscsi/iscsi_ioctl.c:1.3
--- src/sys/dev/iscsi/iscsi_ioctl.c:1.2 Fri Jan 27 19:48:39 2012
+++ src/sys/dev/iscsi/iscsi_ioctl.c Sat Jun 9 06:19:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_ioctl.c,v 1.2 2012/01/27 19:48:39 para Exp $ */
+/* $NetBSD: iscsi_ioctl.c,v 1.3 2012/06/09 06:19:58 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -207,7 +207,8 @@ check_event(iscsi_wait_event_parameters_
}
handler->waiter = par;
splx(s);
- tsleep(par, PRIBIO, "iscsievtwait", 0);
+ if (tsleep(par, PRIBIO | PCATCH, "iscsievtwait", 0))
+ return;
}
} while (evt == NULL);
@@ -324,15 +325,34 @@ get_socket(int fdes, struct file **fpp)
if (fp->f_type != DTYPE_SOCKET) {
return ENOTSOCK;
}
+
/* Add the reference */
+ mutex_enter(&fp->f_lock);
fp->f_count++;
-
- /*simple_unlock (&fp->f_slock); */
+ mutex_exit(&fp->f_lock);
*fpp = fp;
return 0;
}
+/*
+ * release_socket:
+ * Release the file pointer from the socket handle passed into login.
+ *
+ * Parameter:
+ * fp IN: The pointer to the resulting file pointer
+ *
+ */
+
+STATIC void
+release_socket(struct file *fp)
+{
+ /* Add the reference */
+ mutex_enter(&fp->f_lock);
+ fp->f_count--;
+ mutex_exit(&fp->f_lock);
+}
+
/*
* find_session:
@@ -635,6 +655,7 @@ create_connection(iscsi_login_parameters
"ConnRcv")) != 0) {
DEBOUT(("Can't create rcv thread (rc %d)\n", rc));
+ release_socket(connection->sock);
free(connection, M_DEVBUF);
par->status = ISCSI_STATUS_NO_RESOURCES;
return rc;
@@ -653,18 +674,15 @@ create_connection(iscsi_login_parameters
*/
DEBC(connection, 1,
("Closing Socket %p\n", connection->sock));
-#if __NetBSD_Version__ > 500000000
mutex_enter(&connection->sock->f_lock);
connection->sock->f_count += 1;
mutex_exit(&connection->sock->f_lock);
-#else
- FILE_USE(connection->sock);
-#endif
closef(connection->sock);
/* give receive thread time to exit */
tsleep(connection, PWAIT, "settle", 20);
+ release_socket(connection->sock);
free(connection, M_DEVBUF);
par->status = ISCSI_STATUS_NO_RESOURCES;
return rc;
@@ -698,6 +716,9 @@ create_connection(iscsi_login_parameters
session->mru_connection = connection;
CS_END;
+ /* close the file descriptor */
+ fd_close(par->socket);
+
DEBC(connection, 5, ("Connection created successfully!\n"));
return 0;
}
@@ -809,6 +830,10 @@ recreate_connection(iscsi_login_paramete
DEBC(connection, 5, ("Connection ReCreated successfully - status %d\n",
par->status));
+
+ /* close the file descriptor */
+ fd_close(par->socket);
+
return 0;
}
@@ -1463,9 +1488,8 @@ iscsi_cleanup_thread(void *par)
while (conn->sendproc || conn->rcvproc)
tsleep(conn, PWAIT, "termwait", 20);
- /* just in case any CCB is still being processed */
- /* that references this connection */
- tsleep(conn, PWAIT, "finalwait", 20);
+ while (conn->usecount > 0)
+ tsleep(conn, PWAIT, "finalwait", 20);
free(conn, M_DEVBUF);
Index: src/sys/dev/iscsi/iscsi_send.c
diff -u src/sys/dev/iscsi/iscsi_send.c:1.2 src/sys/dev/iscsi/iscsi_send.c:1.3
--- src/sys/dev/iscsi/iscsi_send.c:1.2 Tue Jun 5 16:36:07 2012
+++ src/sys/dev/iscsi/iscsi_send.c Sat Jun 9 06:19:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_send.c,v 1.2 2012/06/05 16:36:07 mhitch Exp $ */
+/* $NetBSD: iscsi_send.c,v 1.3 2012/06/09 06:19:58 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -199,6 +199,8 @@ reassign_tasks(connection_t *oldconn)
ccb->pdu_waiting = pdu;
ccb->connection = conn;
ccb->num_timeouts = 0;
+ oldconn->usecount--;
+ conn->usecount++;
DEBC(conn, 1, ("CCB %p: Copied PDU %p to %p\n",
ccb, opdu, pdu));
@@ -341,25 +343,15 @@ iscsi_send_thread(void *par)
fp = conn->sock;
- DEBC(conn, 9, ("Closing Socket %p\n", conn->sock));
/*
* We must close the socket here to force the receive
* thread to wake up
*/
+ DEBC(conn, 9, ("Closing Socket %p\n", conn->sock));
solock((struct socket *) fp->f_data);
soshutdown((struct socket *) fp->f_data, SHUT_RDWR);
sounlock((struct socket *) fp->f_data);
-
-#if __NetBSD_Version__ > 500000000
- mutex_enter(&fp->f_lock);
- fp->f_count += 1;
- mutex_exit(&fp->f_lock);
closef(fp);
-#else
- simple_lock(&fp->f_slock);
- FILE_USE(fp);
- closef(fp, NULL);
-#endif
/* wake up any non-reassignable waiting CCBs */
for (ccb = TAILQ_FIRST(&conn->ccbs_waiting); ccb != NULL; ccb = nccb) {
@@ -791,9 +783,13 @@ start_text_negotiation(connection_t *con
ccb_t *ccb;
ccb = get_ccb(conn, TRUE);
+ if (ccb == NULL)
+ return;
pdu = get_pdu(conn);
- if (ccb == NULL || pdu == NULL)
+ if (pdu == NULL) {
+ free_ccb(ccb);
return;
+ }
if (init_text_parameters(conn, ccb)) {
free_ccb(ccb);
@@ -887,10 +883,13 @@ send_send_targets(session_t *session, ui
: ISCSI_STATUS_CONNECTION_FAILED;
ccb = get_ccb(conn, TRUE);
+ if (ccb == NULL)
+ return conn->terminating;
pdu = get_pdu(conn);
- /* can only happen if terminating... */
- if (ccb == NULL || pdu == NULL)
+ if (pdu == NULL) {
+ free_ccb(ccb);
return conn->terminating;
+ }
ccb->flags |= CCBF_SENDTARGET;
@@ -1105,12 +1104,15 @@ send_login(connection_t *conn)
DEBC(conn, 9, ("Send_login\n"));
ccb = get_ccb(conn, TRUE);
- pdu = get_pdu(conn);
-
/* only if terminating (which couldn't possibly happen here, but...) */
- if (ccb == NULL || pdu == NULL) {
+ if (ccb == NULL)
+ return conn->terminating;
+ pdu = get_pdu(conn);
+ if (pdu == NULL) {
+ free_ccb(ccb);
return conn->terminating;
}
+
if ((rc = assemble_login_parameters(conn, ccb, pdu)) >= 0) {
init_login_pdu(conn, pdu, !rc);
setup_tx_uio(pdu, pdu->temp_data_len, pdu->temp_data, FALSE);
@@ -1148,10 +1150,14 @@ send_logout(connection_t *conn, connecti
DEBC(conn, 5, ("Send_logout\n"));
ccb = get_ccb(conn, TRUE);
- ppdu = get_pdu(conn);
/* can only happen if terminating... */
- if (ccb == NULL || ppdu == NULL)
+ if (ccb == NULL)
return conn->terminating;
+ ppdu = get_pdu(conn);
+ if (ppdu == NULL) {
+ free_ccb(ccb);
+ return conn->terminating;
+ }
pdu = &ppdu->pdu;
pdu->Opcode = IOP_Logout_Request | OP_IMMEDIATE;
@@ -1211,10 +1217,14 @@ send_task_management(connection_t *conn,
return ISCSI_STATUS_CANT_REASSIGN;
ccb = get_ccb(conn, xs == NULL);
- ppdu = get_pdu(conn);
/* can only happen if terminating... */
- if (ccb == NULL || ppdu == NULL)
+ if (ccb == NULL)
return conn->terminating;
+ ppdu = get_pdu(conn);
+ if (ppdu == NULL) {
+ free_ccb(ccb);
+ return conn->terminating;
+ }
ccb->xs = xs;
@@ -1392,12 +1402,11 @@ send_command(ccb_t *ccb, ccb_disp_t disp
totlen = 0;
} else {
pdu->Flags = FLAG_WRITE;
+ /* immediate data we can send */
len = min(totlen, conn->max_firstimmed);
- /* this means InitialR2T=Yes or FirstBurstLength=0 */
- if (!len)
- totlen = 0;
- else
- totlen -= len;
+
+ /* can we send more unsolicited data ? */
+ totlen = conn->max_firstdata ? totlen - len : 0;
}
}
@@ -1459,7 +1468,7 @@ send_run_xfer(session_t *session, struct
conn = assign_connection(session, waitok);
if (conn == NULL || conn->terminating || conn->state != ST_FULL_FEATURE) {
- xs->error = XS_REQUEUE;
+ xs->error = XS_SELTIMEOUT;
DEBC(conn, 10, ("run_xfer on dead connection\n"));
scsipi_done(xs);
return;
@@ -1500,6 +1509,7 @@ send_run_xfer(session_t *session, struct
ccb->lun += 0x1000000000000LL;
ccb->cmd[1] += 0x10;
#endif
+ ccb->disp = CCBDISP_SCSIPI;
send_command(ccb, CCBDISP_SCSIPI, waitok, FALSE);
}
@@ -1615,23 +1625,19 @@ ccb_timeout(void *par)
{
ccb_t *ccb = (ccb_t *) par;
connection_t *conn = ccb->connection;
-
PDEBC(conn, 1, ("CCB Timeout, ccb=%x, num_timeouts=%d\n",
(int) ccb, ccb->num_timeouts));
- /* ignore CCB timeouts outside full feature phase */
- if (conn->state != ST_FULL_FEATURE)
- return;
-
ccb->total_tries++;
if (++ccb->num_timeouts > MAX_CCB_TIMEOUTS ||
ccb->total_tries > MAX_CCB_TRIES ||
ccb->disp <= CCBDISP_FREE ||
!ccb->session->ErrorRecoveryLevel) {
- handle_connection_error(conn, ISCSI_STATUS_TIMEOUT,
- (ccb->total_tries <= MAX_CCB_TRIES) ? RECOVER_CONNECTION
- : LOGOUT_CONNECTION);
+ ccb->status = ISCSI_STATUS_TIMEOUT;
+ complete_ccb(ccb);
+
+ handle_connection_error(conn, ISCSI_STATUS_TIMEOUT, RECOVER_CONNECTION);
} else {
if (ccb->data_in && ccb->xfer_len < ccb->data_len) {
/* request resend of all missing data */
Index: src/sys/dev/iscsi/iscsi_main.c
diff -u src/sys/dev/iscsi/iscsi_main.c:1.4 src/sys/dev/iscsi/iscsi_main.c:1.5
--- src/sys/dev/iscsi/iscsi_main.c:1.4 Sat Jun 2 16:52:11 2012
+++ src/sys/dev/iscsi/iscsi_main.c Sat Jun 9 06:19:58 2012
@@ -449,7 +449,6 @@ iscsi_done(ccb_t *ccb)
case ISCSI_STATUS_CHECK_CONDITION:
xs->error = XS_SENSE;
- xs->error = XS_SENSE;
#ifdef ISCSI_DEBUG
{
uint8_t *s = (uint8_t *) (&xs->sense);
Index: src/sys/dev/iscsi/iscsi_utils.c
diff -u src/sys/dev/iscsi/iscsi_utils.c:1.1 src/sys/dev/iscsi/iscsi_utils.c:1.2
--- src/sys/dev/iscsi/iscsi_utils.c:1.1 Sun Oct 23 21:15:02 2011
+++ src/sys/dev/iscsi/iscsi_utils.c Sat Jun 9 06:19:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_utils.c,v 1.1 2011/10/23 21:15:02 agc Exp $ */
+/* $NetBSD: iscsi_utils.c,v 1.2 2012/06/09 06:19:58 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2008 The NetBSD Foundation, Inc.
@@ -244,6 +244,7 @@ get_ccb(connection_t *conn, bool waitok)
ccb->ITT = (ccb->ITT & 0xffffff) | (++sess->itt_id << 24);
ccb->disp = CCBDISP_NOWAIT;
ccb->connection = conn;
+ conn->usecount++;
return ccb;
}
@@ -261,6 +262,9 @@ free_ccb(ccb_t *ccb)
session_t *sess = ccb->session;
pdu_t *pdu;
+ ccb->connection->usecount--;
+ ccb->connection = NULL;
+
ccb->disp = CCBDISP_UNUSED;
/* free temporary data */