Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/iscsi Close file descriptor passed into the kernel o...



details:   https://anonhg.NetBSD.org/src/rev/5f33f18d4e02
branches:  trunk
changeset: 779661:5f33f18d4e02
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Jun 09 06:19:58 2012 +0000

description:
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.

diffstat:

 sys/dev/iscsi/iscsi_globals.h |   3 +-
 sys/dev/iscsi/iscsi_ioctl.c   |  46 +++++++++++++++++++------
 sys/dev/iscsi/iscsi_main.c    |   1 -
 sys/dev/iscsi/iscsi_send.c    |  78 +++++++++++++++++++++++-------------------
 sys/dev/iscsi/iscsi_text.c    |   9 ++--
 sys/dev/iscsi/iscsi_utils.c   |   6 ++-
 6 files changed, 89 insertions(+), 54 deletions(-)

diffs (truncated from 388 to 300 lines):

diff -r b3aeead7008a -r 5f33f18d4e02 sys/dev/iscsi/iscsi_globals.h
--- a/sys/dev/iscsi/iscsi_globals.h     Sat Jun 09 02:57:11 2012 +0000
+++ b/sys/dev/iscsi/iscsi_globals.h     Sat Jun 09 06:19:58 2012 +0000
@@ -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 @@
                                        /* 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;
diff -r b3aeead7008a -r 5f33f18d4e02 sys/dev/iscsi/iscsi_ioctl.c
--- a/sys/dev/iscsi/iscsi_ioctl.c       Sat Jun 09 02:57:11 2012 +0000
+++ b/sys/dev/iscsi/iscsi_ioctl.c       Sat Jun 09 06:19:58 2012 +0000
@@ -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 @@
                        }
                        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 @@
        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 @@
                                "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 @@
                 */
                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 @@
        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 @@
 
        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 @@
                        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);
 
diff -r b3aeead7008a -r 5f33f18d4e02 sys/dev/iscsi/iscsi_main.c
--- a/sys/dev/iscsi/iscsi_main.c        Sat Jun 09 02:57:11 2012 +0000
+++ b/sys/dev/iscsi/iscsi_main.c        Sat Jun 09 06:19:58 2012 +0000
@@ -449,7 +449,6 @@
 
                case ISCSI_STATUS_CHECK_CONDITION:
                        xs->error = XS_SENSE;
-                       xs->error = XS_SENSE;
 #ifdef ISCSI_DEBUG
                        {
                                uint8_t *s = (uint8_t *) (&xs->sense);
diff -r b3aeead7008a -r 5f33f18d4e02 sys/dev/iscsi/iscsi_send.c
--- a/sys/dev/iscsi/iscsi_send.c        Sat Jun 09 02:57:11 2012 +0000
+++ b/sys/dev/iscsi/iscsi_send.c        Sat Jun 09 06:19:58 2012 +0000
@@ -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 @@
                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 @@
 
                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 @@
        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 @@
                        : 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 @@
 
        DEBC(conn, 9, ("Send_login\n"));
        ccb = get_ccb(conn, TRUE);
+       /* only if terminating (which couldn't possibly happen here, but...) */
+       if (ccb == NULL)
+               return conn->terminating;
        pdu = get_pdu(conn);
-
-       /* only if terminating (which couldn't possibly happen here, but...) */
-       if (ccb == NULL || pdu == NULL) {
+       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 @@
 
        DEBC(conn, 5, ("Send_logout\n"));
        ccb = get_ccb(conn, TRUE);
+       /* can only happen if terminating... */
+       if (ccb == NULL)
+               return conn->terminating;
        ppdu = get_pdu(conn);
-       /* can only happen if terminating... */
-       if (ccb == NULL || ppdu == NULL)
+       if (ppdu == NULL) {
+               free_ccb(ccb);
                return conn->terminating;
+       }
 
        pdu = &ppdu->pdu;
        pdu->Opcode = IOP_Logout_Request | OP_IMMEDIATE;
@@ -1211,10 +1217,14 @@
                return ISCSI_STATUS_CANT_REASSIGN;
 
        ccb = get_ccb(conn, xs == NULL);
+       /* can only happen if terminating... */
+       if (ccb == NULL)
+               return conn->terminating;
        ppdu = get_pdu(conn);
-       /* can only happen if terminating... */
-       if (ccb == NULL || ppdu == NULL)
+       if (ppdu == NULL) {
+               free_ccb(ccb);
                return conn->terminating;
+       }
 
        ccb->xs = xs;
 
@@ -1392,12 +1402,11 @@
                        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 @@
        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;



Home | Main Index | Thread Index | Old Index