From patchwork Thu Aug 11 22:29:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Yan X-Patchwork-Id: 9276107 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0218F6022E for ; Thu, 11 Aug 2016 22:30:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E0A942878A for ; Thu, 11 Aug 2016 22:30:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D3063287AC; Thu, 11 Aug 2016 22:30:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61AFA2878A for ; Thu, 11 Aug 2016 22:30:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752617AbcHKW3z (ORCPT ); Thu, 11 Aug 2016 18:29:55 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:33355 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751288AbcHKW3v (ORCPT ); Thu, 11 Aug 2016 18:29:51 -0400 Received: by mail-pf0-f194.google.com with SMTP id i6so417403pfe.0; Thu, 11 Aug 2016 15:29:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=nVNvJfHS5X36yV6d1U1AsbOuWx5UQIWQAj/iyEnBH2w=; b=A2nU4zf/fELec+zskyu+ilvzw3BLD1AYDvjxcup2ui+reO8rkTPW0x8qGvAMYi8VjH KEyILyEG81lKtRaVpJXU3uQBBnCMxWQZ2mdY2nm9BUs27zC1Kld0gZuQg+/+WlnJpkXa EgQg8ty3XE5t6Nr1P2c7PWNGc1uLFtMBNPR7loOafxuWwltVTq6gaBK7r0sv9jWY+HpH UiiXaQ1uOTvTBJqgFQViLZvg+GozMVE+SaLRJhG2P/ZjQu3FcjYRz5bt7yPLx2UbFCV4 Ajftyi20DMPMTYQaxgAvxR2laFeqdB10x4V6elLwVmRNyHByNy5BIQm9J9adt3mRcWav e66g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=nVNvJfHS5X36yV6d1U1AsbOuWx5UQIWQAj/iyEnBH2w=; b=Fphu/ZRCFvLU3YDg7NALUhfOvoOsPWaMNBv0hlDg5G78u8f4NPvBxu0GrgwAuYskG+ mDSq6Q83IHF3xPojsQeM/CSBqOn5y/P0ODYE6CJk279G+ekFSWqFItTcjy8bAK9Ps60e Y6FkfJZax5VsmN1JEiSc3+OSqPnr/69SiqG+AF8g1+slqRbS+ahngbYgSI4JLtsPao4T NxdfImxneqYlkX1itVWXBzKLpB5qhyihPAbKfLvndyfXpgp4fn25kMS9sWclwIn8RAyR E4qt33wVNwqjgHbSyY8uT/wJkaFEE9ZIuU3V2dD19WksRQBy3tg9PK6DevQG/VzkP7bC VdtA== X-Gm-Message-State: AEkoouueHvUFK7wAunq3PySWtMPKetpLBTE+K+L3kmKMx9SnrXt9dh09C9a3Bp//F2zBaA== X-Received: by 10.98.33.72 with SMTP id h69mr21338479pfh.28.1470954590857; Thu, 11 Aug 2016 15:29:50 -0700 (PDT) Received: from localhost.localdomain ([2404:c805:e00:4700:ae22:bff:fe29:e60c]) by smtp.gmail.com with ESMTPSA id s23sm7631766pfd.23.2016.08.11.15.29.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 Aug 2016 15:29:50 -0700 (PDT) From: tom.ty89@gmail.com X-Google-Original-From: me To: martin.petersen@oracle.com, shaun@tancheff.com Cc: linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, shaun.tancheff@seagate.com, Tom Yan Subject: [RFC] sd: dynamically adjust SD_MAX_WS16_BLOCKS as per the actual logical block size Date: Fri, 12 Aug 2016 06:29:43 +0800 Message-Id: X-Mailer: git-send-email 2.9.2 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Tom Yan WRITE SAME (16) command can technically handle up to 32-bit number of blocks. However, since 32-bit is also the limitation of the maximum number of bytes that can be represented in the block layer, the current SD_MAX_WS16_BLOCKS was hence derived from the technical limit devided by 512. However, SD_MAX_WS16_BLOCKS is used to check values that are, for example, orignated from Maximum Write Same Length field on the Block Limit VPD. Such field expresses the number of blocks in terms of the actual logical sector size of the specific drive instead of the block size that the block layer is based on (512). Therefore, the original hack would work fine for drives with 512-byte logical sectors. However, for drives with larger logical sector size (e.g. AF 4Kn drives), the hack would be in vain. So let's bump the macro set in sd.h back to the technical limit, and adjust it as per the actual logical block size when it is used. Signed-off-by: Tom Yan diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d3e852a..601afd6 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -452,6 +452,8 @@ max_write_same_blocks_store(struct device *dev, struct device_attribute *attr, { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; + unsigned int logical_block_size = sdp->sector_size; + unsigned int max_ws16_blocks = SD_MAX_WS16_BLOCKS / logical_block_size; unsigned long max; int err; @@ -468,7 +470,7 @@ max_write_same_blocks_store(struct device *dev, struct device_attribute *attr, if (max == 0) sdp->no_write_same = 1; - else if (max <= SD_MAX_WS16_BLOCKS) { + else if (max <= max_ws16_blocks) { sdp->no_write_same = 0; sdkp->max_ws_blocks = max; } @@ -635,6 +637,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) { struct request_queue *q = sdkp->disk->queue; unsigned int logical_block_size = sdkp->device->sector_size; + unsigned int max_ws16_blocks = SD_MAX_WS16_BLOCKS / logical_block_size; unsigned int max_blocks = 0; q->limits.discard_zeroes_data = 0; @@ -668,12 +671,12 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) case SD_LBP_UNMAP: max_blocks = min_not_zero(sdkp->max_unmap_blocks, - (u32)SD_MAX_WS16_BLOCKS); + (u32)max_ws16_blocks); break; case SD_LBP_WS16: max_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); + (u32)max_ws16_blocks); q->limits.discard_zeroes_data = sdkp->lbprz; break; @@ -793,6 +796,7 @@ static void sd_config_write_same(struct scsi_disk *sdkp) { struct request_queue *q = sdkp->disk->queue; unsigned int logical_block_size = sdkp->device->sector_size; + unsigned int max_ws16_blocks = SD_MAX_WS16_BLOCKS / logical_block_size; if (sdkp->device->no_write_same) { sdkp->max_ws_blocks = 0; @@ -806,7 +810,7 @@ static void sd_config_write_same(struct scsi_disk *sdkp) */ if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); + (u32)max_ws16_blocks); else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes) sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)SD_MAX_WS10_BLOCKS); diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 765a6f1..56ff88c 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -47,7 +47,7 @@ enum { SD_DEF_XFER_BLOCKS = 0xffff, SD_MAX_XFER_BLOCKS = 0xffffffff, SD_MAX_WS10_BLOCKS = 0xffff, - SD_MAX_WS16_BLOCKS = 0x7fffff, + SD_MAX_WS16_BLOCKS = 0xffffffff, }; enum {