Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/scsipi Don't waste too much kernel stack space on (i...



details:   https://anonhg.NetBSD.org/src/rev/c5b13f0a7367
branches:  trunk
changeset: 540461:c5b13f0a7367
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Sun Dec 15 01:55:44 2002 +0000

description:
Don't waste too much kernel stack space on (infrequent) ioctl operations,
use malloc instead for temp space.

diffstat:

 sys/dev/scsipi/cd.c |  94 +++++++++++++++++++++++++++++++++-------------------
 sys/dev/scsipi/sd.c |  60 +++++++++++++++++++++-----------
 2 files changed, 99 insertions(+), 55 deletions(-)

diffs (300 lines):

diff -r 2fb91e4b7154 -r c5b13f0a7367 sys/dev/scsipi/cd.c
--- a/sys/dev/scsipi/cd.c       Sun Dec 15 00:40:24 2002 +0000
+++ b/sys/dev/scsipi/cd.c       Sun Dec 15 01:55:44 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd.c,v 1.170 2002/11/09 18:58:26 thorpej Exp $ */
+/*     $NetBSD: cd.c,v 1.171 2002/12/15 01:55:44 fvdl Exp $    */
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.170 2002/11/09 18:58:26 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.171 2002/12/15 01:55:44 fvdl Exp $");
 
 #include "rnd.h"
 
@@ -1098,9 +1098,9 @@
        struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
        struct scsipi_periph *periph = cd->sc_periph;
        int part = CDPART(dev);
-       int error;
+       int error = 0;
 #ifdef __HAVE_OLD_DISKLABEL
-       struct disklabel newlabel;
+       struct disklabel *newlabel = NULL;
 #endif
 
        SC_DEBUG(cd->sc_periph, SCSIPI_DB2, ("cdioctl 0x%lx ", cmd));
@@ -1154,11 +1154,16 @@
                return (0);
 #ifdef __HAVE_OLD_DISKLABEL
        case ODIOCGDINFO:
-               newlabel = *(cd->sc_dk.dk_label);
-               if (newlabel.d_npartitions > OLDMAXPARTITIONS)
-                       return ENOTTY;
-               memcpy(addr, &newlabel, sizeof (struct olddisklabel));
-               return (0);
+               newlabel = malloc(sizeof (*newlabel), M_TEMP, M_WAITOK);
+               if (newlabel == NULL)
+                       return (EIO);
+               memcpy(newlabel, cd->sc_dk.dk_label, sizeof (*newlabel));
+               if (newlabel->d_npartitions > OLDMAXPARTITIONS)
+                       error = ENOTTY;
+               else
+                       memcpy(addr, newlabel, sizeof (struct olddisklabel));
+               free(newlabel, M_TEMP);
+               return error;
 #endif
 
        case DIOCGPART:
@@ -1176,20 +1181,23 @@
        {
                struct disklabel *lp;
 
+               if ((flag & FWRITE) == 0)
+                       return (EBADF);
+
 #ifdef __HAVE_OLD_DISKLABEL
                if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
-                       memset(&newlabel, 0, sizeof newlabel);
-                       memcpy(&newlabel, addr, sizeof (struct olddisklabel));
-                       lp = &newlabel;
+                       newlabel = malloc(sizeof (*newlabel), M_TEMP, M_WAITOK);
+                       if (newlabel == NULL)
+                               return (EIO);
+                       memset(newlabel, 0, sizeof newlabel);
+                       memcpy(newlabel, addr, sizeof (struct olddisklabel));
+                       lp = newlabel;
                } else
 #endif
                lp = (struct disklabel *)addr;
 
-               if ((flag & FWRITE) == 0)
-                       return (EBADF);
-
                if ((error = cdlock(cd)) != 0)
-                       return (error);
+                       goto bad;
                cd->flags |= CDF_LABELLING;
 
                error = setdisklabel(cd->sc_dk.dk_label,
@@ -1201,6 +1209,11 @@
 
                cd->flags &= ~CDF_LABELLING;
                cdunlock(cd);
+bad:
+#ifdef __HAVE_OLD_DISKLABEL
+               if (newlabel != NULL)
+                       free(newlabel, M_TEMP);
+#endif
                return (error);
        }
 
@@ -1213,11 +1226,16 @@
 
 #ifdef __HAVE_OLD_DISKLABEL
        case ODIOCGDEFLABEL:
-               cdgetdefaultlabel(cd, &newlabel);
-               if (newlabel.d_npartitions > OLDMAXPARTITIONS)
-                       return ENOTTY;
-               memcpy(addr, &newlabel, sizeof (struct olddisklabel));
-               return (0);
+               newlabel = malloc(sizeof (*newlabel), M_TEMP, M_WAITOK);
+               if (newlabel == NULL)
+                       return (EIO);
+               cdgetdefaultlabel(cd, newlabel);
+               if (newlabel->d_npartitions > OLDMAXPARTITIONS)
+                       error = ENOTTY;
+               else
+                       memcpy(addr, newlabel, sizeof (struct olddisklabel));
+               free(newlabel, M_TEMP);
+               return error;
 #endif
 
        case CDIOCPLAYTRACKS: {
@@ -2032,9 +2050,12 @@
        dvd_struct *s;
 {
        struct scsipi_generic cmd;
-       u_int8_t buf[4 + 2048];
+       u_int8_t *buf;
        int error;
 
+       buf = malloc(4 + 2048, M_TEMP, M_WAITOK);
+       if (buf == NULL)
+               return EIO;
        memset(cmd.bytes, 0, 15);
        memset(buf, 0, sizeof(buf));
        cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
@@ -2044,10 +2065,10 @@
        cmd.bytes[9] = s->disckey.agid << 6;
        error = scsipi_command(cd->sc_periph, &cmd, 12, buf, sizeof(buf),
            CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
-       if (error)
-               return (error);
-       memcpy(s->disckey.value, &buf[4], 2048);
-       return (0);
+       if (error == 0)
+               memcpy(s->disckey.value, &buf[4], 2048);
+       free(buf, M_TEMP);
+       return error;
 }
 
 int
@@ -2082,9 +2103,12 @@
        dvd_struct *s;
 {
        struct scsipi_generic cmd;
-       u_int8_t buf[4 + 2048];
+       u_int8_t *buf;
        int error;
 
+       buf = malloc(4 + 2048, M_TEMP, M_WAITOK);
+       if (buf == NULL)
+               return (EIO);
        memset(cmd.bytes, 0, 15);
        memset(buf, 0, sizeof(buf));
        cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
@@ -2093,13 +2117,15 @@
 
        error = scsipi_command(cd->sc_periph, &cmd, 12, buf, sizeof(buf),
            CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
-       if (error)
-               return (error);
-       s->manufact.len = _2btol(&buf[0]);
-       if (s->manufact.len < 0 || s->manufact.len > 2048)
-               return (EIO);
-       memcpy(s->manufact.value, &buf[4], s->manufact.len);
-       return (0);
+       if (error == 0) {
+               s->manufact.len = _2btol(&buf[0]);
+               if (s->manufact.len >= 0 && s->manufact.len <= 2048)
+                       memcpy(s->manufact.value, &buf[4], s->manufact.len);
+               else
+                       error = EIO;
+       }
+       free(buf, M_TEMP);
+       return error;
 }
 
 int
diff -r 2fb91e4b7154 -r c5b13f0a7367 sys/dev/scsipi/sd.c
--- a/sys/dev/scsipi/sd.c       Sun Dec 15 00:40:24 2002 +0000
+++ b/sys/dev/scsipi/sd.c       Sun Dec 15 01:55:44 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sd.c,v 1.191 2002/11/01 11:32:00 mrg Exp $     */
+/*     $NetBSD: sd.c,v 1.192 2002/12/15 01:55:44 fvdl Exp $    */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.191 2002/11/01 11:32:00 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.192 2002/12/15 01:55:44 fvdl Exp $");
 
 #include "opt_scsi.h"
 #include "opt_bufq.h"
@@ -908,9 +908,9 @@
        struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)];
        struct scsipi_periph *periph = sd->sc_periph;
        int part = SDPART(dev);
-       int error;
+       int error = 0;
 #ifdef __HAVE_OLD_DISKLABEL
-       struct disklabel newlabel;
+       struct disklabel *newlabel = NULL;
 #endif
 
        SC_DEBUG(sd->sc_periph, SCSIPI_DB2, ("sdioctl 0x%lx ", cmd));
@@ -950,11 +950,16 @@
 
 #ifdef __HAVE_OLD_DISKLABEL
        case ODIOCGDINFO:
-               newlabel = *(sd->sc_dk.dk_label);
-               if (newlabel.d_npartitions > OLDMAXPARTITIONS)
-                       return ENOTTY;
-               memcpy(addr, &newlabel, sizeof (struct olddisklabel));
-               return (0);
+               newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
+               if (newlabel == NULL)
+                       return EIO;
+               memcpy(newlabel, sd->sc_dk.dk_label, sizeof (*newlabel));
+               if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
+                       memcpy(addr, newlabel, sizeof (struct olddisklabel));
+               else
+                       error = ENOTTY;
+               free(newlabel, M_TEMP);
+               return error;
 #endif
 
        case DIOCGPART:
@@ -972,20 +977,23 @@
        {
                struct disklabel *lp;
 
+               if ((flag & FWRITE) == 0)
+                       return (EBADF);
+
 #ifdef __HAVE_OLD_DISKLABEL
                if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
-                       memset(&newlabel, 0, sizeof newlabel);
-                       memcpy(&newlabel, addr, sizeof (struct olddisklabel));
-                       lp = &newlabel;
+                       newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
+                       if (newlabel == NULL)
+                               return EIO;
+                       memset(newlabel, 0, sizeof newlabel);
+                       memcpy(newlabel, addr, sizeof (struct olddisklabel));
+                       lp = newlabel;
                } else
 #endif
                lp = (struct disklabel *)addr;
 
-               if ((flag & FWRITE) == 0)
-                       return (EBADF);
-
                if ((error = sdlock(sd)) != 0)
-                       return (error);
+                       goto bad;
                sd->flags |= SDF_LABELLING;
 
                error = setdisklabel(sd->sc_dk.dk_label,
@@ -1004,6 +1012,11 @@
 
                sd->flags &= ~SDF_LABELLING;
                sdunlock(sd);
+bad:
+#ifdef __HAVE_OLD_DISKLABEL
+               if (newlabel != NULL)
+                       free(newlabel, M_TEMP);
+#endif
                return (error);
        }
 
@@ -1057,11 +1070,16 @@
 
 #ifdef __HAVE_OLD_DISKLABEL
        case ODIOCGDEFLABEL:
-               sdgetdefaultlabel(sd, &newlabel);
-               if (newlabel.d_npartitions > OLDMAXPARTITIONS)
-                       return ENOTTY;
-               memcpy(addr, &newlabel, sizeof (struct olddisklabel));
-               return (0);
+               newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
+               if (newlabel == NULL)
+                       return EIO;
+               sdgetdefaultlabel(sd, newlabel);
+               if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
+                       memcpy(addr, newlabel, sizeof (struct olddisklabel));
+               else
+                       error = ENOTTY;
+               free(newlabel, M_TEMP);
+               return error;
 #endif
 
        case DIOCGCACHE:



Home | Main Index | Thread Index | Old Index