Source-Changes-HG archive

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

[src/netbsd-7-0]: src/sys/dev/scsipi Pull up following revision(s) (requested...



details:   https://anonhg.NetBSD.org/src/rev/c04b4b1633e7
branches:  netbsd-7-0
changeset: 449456:c04b4b1633e7
user:      martin <martin%NetBSD.org@localhost>
date:      Thu Mar 07 16:51:50 2019 +0000

description:
Pull up following revision(s) (requested by kardel in ticket #1682):

        sys/dev/scsipi/st.c: revision 1.236 (patch)
        sys/dev/scsipi/st.c: revision 1.237
        sys/dev/scsipi/files.scsipi: revision 1.42

Fix PR kern/53949:
Fix inconsistent/incomplete file mark handling to conform again
to mtio(4) at close(2) time. This was necessary as the PREVENT/ALLOW
bracket was reduced from a whole mount session to cover only the
open(2)/close(2) time on ~2002-03-22. The rationale was to allow
robots and humans to change the media during a mount session.

Unfortunately this lead to file marks being written to potentially other
media at the beginning on drives that used the two file marks as EOM
pattern. In order for that to happen the media had to be removed after
data and at most one file mark had been written before removal.

The mount error message has been clarified and a warning about
potential data/file mark lossage on UNIT ATTENTION
during an active mount session with unfinished file marks has been
added.

While there, fix, but disable the commented SUN compatibility to write
final file marks by opening and immediately closing the device
in O_WRONLY mode. That code has not been working since around 1998.

It can now be enabled with options ST_SUNCOMPAT.

Additionally debug output coverage has been extended.

Correct printing type of b_blkno (int64_t) in st.c

Fixes build with kUBSan on NetBSD/i386.

Fix, but disable the commented SUN compatibility in st.c to write
final file marks by opening and immediately closing the device
in O_WRONLY mode. That code has not been working since around 1998.
It can now be enabled with options ST_SUNCOMPAT.

diffstat:

 sys/dev/scsipi/files.scsipi |   5 +-
 sys/dev/scsipi/st.c         |  92 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 82 insertions(+), 15 deletions(-)

diffs (206 lines):

diff -r 707f852b883f -r c04b4b1633e7 sys/dev/scsipi/files.scsipi
--- a/sys/dev/scsipi/files.scsipi       Sun Feb 24 10:55:50 2019 +0000
+++ b/sys/dev/scsipi/files.scsipi       Thu Mar 07 16:51:50 2019 +0000
@@ -1,11 +1,12 @@
-#      $NetBSD: files.scsipi,v 1.41 2005/12/11 12:23:50 christos Exp $
+#      $NetBSD: files.scsipi,v 1.41.142.1 2019/03/07 16:51:50 martin Exp $
 #
 # Config file and device description for machine-independent SCSI code.
 # Included by ports that need it.  Ports that use it must provide
 # their own "major" declarations for the appropriate devices.
 
 defflag        opt_scsi.h              SCSIVERBOSE ST_ENABLE_EARLYWARN
-                               SES_ENABLE_PASSTHROUGH SCSI_OLD_NOINQUIRY
+                               ST_SUNCOMPAT SES_ENABLE_PASSTHROUGH
+                               SCSI_OLD_NOINQUIRY
 defparam opt_scsi.h            ST_MOUNT_DELAY SDRETRIES SD_IO_TIMEOUT
 
 defflag        opt_scsipi_debug.h      SCSIPI_DEBUG
diff -r 707f852b883f -r c04b4b1633e7 sys/dev/scsipi/st.c
--- a/sys/dev/scsipi/st.c       Sun Feb 24 10:55:50 2019 +0000
+++ b/sys/dev/scsipi/st.c       Thu Mar 07 16:51:50 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: st.c,v 1.226 2014/08/10 16:44:36 tls Exp $ */
+/*     $NetBSD: st.c,v 1.226.6.1 2019/03/07 16:51:50 martin Exp $ */
 
 /*-
  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.226 2014/08/10 16:44:36 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.226.6.1 2019/03/07 16:51:50 martin Exp $");
 
 #include "opt_scsi.h"
 
@@ -605,6 +605,30 @@
                 */
                if ((st->flags & ST_MOUNTED) || ST_MOUNT_DELAY == 0 ||
                    (st->mt_key != SKEY_NOT_READY)) {
+                       device_printf(st->sc_dev,
+                                     "mount error (sense key=%d) - "
+                                     "terminating mount session\n",
+                                     st->mt_key);
+                       /*
+                        * the following should not trigger unless
+                        * something serious happened while the device
+                        * was open (PREVENT MEDIUM REMOVAL in effect)
+                        */
+                       if (st->flags & ST_WRITTEN &&
+                           st->mt_key == SKEY_UNIT_ATTENTION) {
+                               /*
+                                * device / media state may have changed
+                                * refrain from writing missing file marks
+                                * onto potentially newly inserted/formatted
+                                * media (e. g. emergency EJECT/RESET/etc.)
+                                */
+                               st->flags &= ~(ST_WRITTEN|ST_FM_WRITTEN);
+
+                               device_printf(st->sc_dev,
+                                    "CAUTION: file marks/data may be missing"
+                                    " - ASC = 0x%02x, ASCQ = 0x%02x\n",
+                                             st->asc, st->ascq);
+                       }
                        goto bad;
                }
 
@@ -713,15 +737,30 @@
         */
 
        stxx = st->flags & (ST_WRITTEN | ST_FM_WRITTEN);
-       if (((flags & FWRITE) && stxx == ST_WRITTEN) ||
-           ((flags & O_ACCMODE) == FWRITE && stxx == 0)) {
-               int nm;
+       if ((flags & FWRITE) != 0) {
+               int nm = 0;
+#ifdef ST_SUNCOMPAT
+               /*
+                * on request only
+                * original compat code has not been working
+                * since ~1998
+                */
+               if ((flags & O_ACCMODE) == FWRITE && (stxx == 0)) {
+                       st->flags |= ST_WRITTEN;
+                       SC_DEBUG(st->sc_periph, SCSIPI_DB3,
+                                ("SUN compatibility: write FM(s) at close\n"));
+               }
+#endif
                error = st_check_eod(st, FALSE, &nm, 0);
+               SC_DEBUG(st->sc_periph, SCSIPI_DB3,
+                        ("wrote %d FM(s) at close error=%d\n", nm, error));
        }
 
        /* Allow robots to eject tape if needed.  */
-       scsipi_prevent(periph, SPAMR_ALLOW,
-           XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY);
+       if (!(st->quirks & ST_Q_NOPREVENT)) {
+               scsipi_prevent(periph, SPAMR_ALLOW,
+                   XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY);
+       }
 
        switch (STMODE(dev)) {
        case NORMAL_MODE:
@@ -755,18 +794,28 @@
                         * If both statements are true, then we backspace
                         * one filemark.
                         */
+                       stxx &= ~ST_FM_WRITTEN;
                        stxx |= (st->flags & ST_2FM_AT_EOD);
                        if ((flags & FWRITE) != 0 &&
                            (stxx == (ST_2FM_AT_EOD|ST_WRITTEN))) {
                                error = st_space(st, -1, SP_FILEMARKS, 0);
+                               SC_DEBUG(st->sc_periph, SCSIPI_DB3, ("st_space(-1) error=%d\n", error));
+                       } else {
+                               SC_DEBUG(st->sc_periph, SCSIPI_DB3, ("no backspacing - flags = 0x%x, stxx=0x%x, st->flags=0x%x\n", flags, stxx, st->flags));
                        }
+               } else {
+                       SC_DEBUG(st->sc_periph, SCSIPI_DB3, ("error %d from st_check_eod\n", error));
                }
+       
                break;
        case EJECT_MODE:
                st_unmount(st, EJECT);
                break;
        }
 
+       KASSERTMSG((st->flags & ST_WRITTEN) == 0,
+                  "pending ST_WRITTEN flag NOT cleared (flags=0x%x)", st->flags);
+       
        scsipi_wait_drain(periph);
 
        scsipi_adapter_delref(adapt);
@@ -894,7 +943,7 @@
 
        /*
         * Section 9.3.3 of the SCSI specs states that a device shall return
-        * the density value specified in the last succesfull MODE SELECT
+        * the density value specified in the last successful MODE SELECT
         * after an unload operation, in case it is not able to
         * automatically determine the density of the new medium.
         *
@@ -1051,6 +1100,8 @@
 
        /* If offset is negative, error */
        if (bp->b_blkno < 0) {
+               SC_DEBUG(periph, SCSIPI_DB3,
+                        ("EINVAL: ststrategy negative blockcount %" PRId64 "\n", bp->b_blkno));
                bp->b_error = EINVAL;
                goto abort;
        }
@@ -1313,8 +1364,12 @@
 {
        struct st_softc *st = device_lookup_private(&st_cd, STUNIT(dev));
 
-       return physio(ststrategy, NULL, dev, B_READ,
-           st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio);
+       int r = physio(ststrategy, NULL, dev, B_READ,
+                      st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio);
+
+       SC_DEBUG(st->sc_periph, SCSIPI_DB1, ("[stread: result=%d]\n", r));
+
+       return r;
 }
 
 static int
@@ -1322,8 +1377,12 @@
 {
        struct st_softc *st = device_lookup_private(&st_cd, STUNIT(dev));
 
-       return physio(ststrategy, NULL, dev, B_WRITE,
+       int r = physio(ststrategy, NULL, dev, B_WRITE,
            st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio);
+
+       SC_DEBUG(st->sc_periph, SCSIPI_DB1, ("[stwrite: result=%d]\n", r));
+
+       return r;
 }
 
 /*
@@ -1734,8 +1793,12 @@
         * It's hard to write a negative number of file marks.
         * Don't try.
         */
-       if (number < 0)
+       if (number < 0) {
+               SC_DEBUG(st->sc_periph, SCSIPI_DB3,
+                        ("EINVAL: st_write_filemarks not writing %d file marks\n", number));
                return EINVAL;
+       }
+       
        switch (number) {
        case 0:         /* really a command to sync the drive's buffers */
                break;
@@ -1930,8 +1993,11 @@
                        printf("%02x ", posdata[hard] & 0xff);
                printf("\n");
 #endif
-               if (posdata[0] & 0x4)   /* Block Position Unknown */
+               if (posdata[0] & 0x4) { /* Block Position Unknown */
+                       SC_DEBUG(st->sc_periph, SCSIPI_DB3,
+                                ("EINVAL: strdpos block position unknown\n"));
                        error = EINVAL;
+               }       
                else
                        *blkptr = _4btol(&posdata[4]);
        }



Home | Main Index | Thread Index | Old Index