Print this page
3515 sd gives RMW warnings for reads
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2011 Bayard G. Bell.  All rights reserved.
  28  * Copyright (c) 2012 by Delphix. All rights reserved.

  29  */
  30 /*
  31  * Copyright 2011 cyril.galibern@opensvc.com
  32  */
  33 
  34 /*
  35  * SCSI disk target driver.
  36  */
  37 #include <sys/scsi/scsi.h>
  38 #include <sys/dkbad.h>
  39 #include <sys/dklabel.h>
  40 #include <sys/dkio.h>
  41 #include <sys/fdio.h>
  42 #include <sys/cdio.h>
  43 #include <sys/mhd.h>
  44 #include <sys/vtoc.h>
  45 #include <sys/dktp/fdisk.h>
  46 #include <sys/kstat.h>
  47 #include <sys/vtrace.h>
  48 #include <sys/note.h>


12630                 blknomask = (un->un_phy_blocksize / DEV_BSIZE) - 1;
12631                 secmask = un->un_phy_blocksize - 1;
12632         } else {
12633                 blknomask = (un->un_tgt_blocksize / DEV_BSIZE) - 1;
12634                 secmask = un->un_tgt_blocksize - 1;
12635         }
12636 
12637         if ((bp->b_lblkno & (blknomask)) || (bp->b_bcount & (secmask))) {
12638                 is_aligned = FALSE;
12639         }
12640 
12641         if (!(NOT_DEVBSIZE(un)) || un->un_f_enable_rmw) {
12642                 /*
12643                  * If I/O is aligned, no need to involve RMW(Read Modify Write)
12644                  * Convert the logical block number to target's physical sector
12645                  * number.
12646                  */
12647                 if (is_aligned) {
12648                         xp->xb_blkno = SD_SYS2TGTBLOCK(un, xp->xb_blkno);
12649                 } else {
12650                         switch (un->un_f_rmw_type) {
12651                         case SD_RMW_TYPE_RETURN_ERROR:
12652                                 if (un->un_f_enable_rmw)
12653                                         break;
12654                                 else {



12655                                         bp->b_flags |= B_ERROR;
12656                                         goto error_exit;
12657                                 }
12658 
12659                         case SD_RMW_TYPE_DEFAULT:
12660                                 mutex_enter(SD_MUTEX(un));
12661                                 if (!un->un_f_enable_rmw &&
12662                                     un->un_rmw_msg_timeid == NULL) {
12663                                         scsi_log(SD_DEVINFO(un), sd_label,
12664                                             CE_WARN, "I/O request is not "
12665                                             "aligned with %d disk sector size. "
12666                                             "It is handled through Read Modify "
12667                                             "Write but the performance is "
12668                                             "very low.\n",
12669                                             un->un_tgt_blocksize);
12670                                         un->un_rmw_msg_timeid =
12671                                             timeout(sd_rmw_msg_print_handler,
12672                                             un, SD_RMW_MSG_PRINT_TIMEOUT);
12673                                 } else {
12674                                         un->un_rmw_incre_count ++;
12675                                 }
12676                                 mutex_exit(SD_MUTEX(un));
12677                                 break;
12678 
12679                         case SD_RMW_TYPE_NO_WARNING:
12680                         default:
12681                                 break;
12682                         }
12683 
12684                         nblocks = SD_TGT2SYSBLOCK(un, nblocks);
12685                         partition_offset = SD_TGT2SYSBLOCK(un,
12686                             partition_offset);
12687                 }
12688         }
12689 
12690         /*
12691          * blocknum is the starting block number of the request. At this
12692          * point it is still relative to the start of the minor device.
12693          */
12694         blocknum = xp->xb_blkno;
12695 
12696         /*
12697          * Legacy: If the starting block number is one past the last block
12698          * in the partition, do not set B_ERROR in the buf.
12699          */
12700         if (blocknum == nblocks)  {
12701                 goto error_exit;




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*

  26  * Copyright (c) 2011 Bayard G. Bell.  All rights reserved.
  27  * Copyright (c) 2012 by Delphix. All rights reserved.
  28  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  29  */
  30 /*
  31  * Copyright 2011 cyril.galibern@opensvc.com
  32  */
  33 
  34 /*
  35  * SCSI disk target driver.
  36  */
  37 #include <sys/scsi/scsi.h>
  38 #include <sys/dkbad.h>
  39 #include <sys/dklabel.h>
  40 #include <sys/dkio.h>
  41 #include <sys/fdio.h>
  42 #include <sys/cdio.h>
  43 #include <sys/mhd.h>
  44 #include <sys/vtoc.h>
  45 #include <sys/dktp/fdisk.h>
  46 #include <sys/kstat.h>
  47 #include <sys/vtrace.h>
  48 #include <sys/note.h>


12630                 blknomask = (un->un_phy_blocksize / DEV_BSIZE) - 1;
12631                 secmask = un->un_phy_blocksize - 1;
12632         } else {
12633                 blknomask = (un->un_tgt_blocksize / DEV_BSIZE) - 1;
12634                 secmask = un->un_tgt_blocksize - 1;
12635         }
12636 
12637         if ((bp->b_lblkno & (blknomask)) || (bp->b_bcount & (secmask))) {
12638                 is_aligned = FALSE;
12639         }
12640 
12641         if (!(NOT_DEVBSIZE(un)) || un->un_f_enable_rmw) {
12642                 /*
12643                  * If I/O is aligned, no need to involve RMW(Read Modify Write)
12644                  * Convert the logical block number to target's physical sector
12645                  * number.
12646                  */
12647                 if (is_aligned) {
12648                         xp->xb_blkno = SD_SYS2TGTBLOCK(un, xp->xb_blkno);
12649                 } else {
12650                         /*
12651                          * There is no RMW if we're just reading, so don't
12652                          * warn or error out because of it.
12653                          */
12654                         if (bp->b_flags & B_READ) {
12655                                 /*EMPTY*/
12656                         } else if (!un->un_f_enable_rmw &&
12657                             un->un_f_rmw_type == SD_RMW_TYPE_RETURN_ERROR) {
12658                                 bp->b_flags |= B_ERROR;
12659                                 goto error_exit;
12660                         } else if (un->un_f_rmw_type == SD_RMW_TYPE_DEFAULT) {


12661                                 mutex_enter(SD_MUTEX(un));
12662                                 if (!un->un_f_enable_rmw &&
12663                                     un->un_rmw_msg_timeid == NULL) {
12664                                         scsi_log(SD_DEVINFO(un), sd_label,
12665                                             CE_WARN, "I/O request is not "
12666                                             "aligned with %d disk sector size. "
12667                                             "It is handled through Read Modify "
12668                                             "Write but the performance is "
12669                                             "very low.\n",
12670                                             un->un_tgt_blocksize);
12671                                         un->un_rmw_msg_timeid =
12672                                             timeout(sd_rmw_msg_print_handler,
12673                                             un, SD_RMW_MSG_PRINT_TIMEOUT);
12674                                 } else {
12675                                         un->un_rmw_incre_count ++;
12676                                 }
12677                                 mutex_exit(SD_MUTEX(un));





12678                         }
12679 
12680                         nblocks = SD_TGT2SYSBLOCK(un, nblocks);
12681                         partition_offset = SD_TGT2SYSBLOCK(un,
12682                             partition_offset);
12683                 }
12684         }
12685 
12686         /*
12687          * blocknum is the starting block number of the request. At this
12688          * point it is still relative to the start of the minor device.
12689          */
12690         blocknum = xp->xb_blkno;
12691 
12692         /*
12693          * Legacy: If the starting block number is one past the last block
12694          * in the partition, do not set B_ERROR in the buf.
12695          */
12696         if (blocknum == nblocks)  {
12697                 goto error_exit;