From patchwork Mon Apr 11 23:42:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Mostafa X-Patchwork-Id: 609193 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3qkRV51QBdz9ssP; Tue, 12 Apr 2016 09:43:57 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1aplUo-0002KH-4p; Mon, 11 Apr 2016 23:43:54 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1aplTI-0001hV-6z for kernel-team@lists.ubuntu.com; Mon, 11 Apr 2016 23:42:20 +0000 Received: from 1.general.kamal.us.vpn ([10.172.68.52] helo=fourier) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1aplTH-0000UK-Oc; Mon, 11 Apr 2016 23:42:19 +0000 Received: from kamal by fourier with local (Exim 4.86_2) (envelope-from ) id 1aplTF-0005ow-1S; Mon, 11 Apr 2016 16:42:17 -0700 From: Kamal Mostafa To: "Martin K. Petersen" Subject: [3.19.y-ckt stable] Patch "sd: Fix excessive capacity printing on devices with blocks bigger than 512 bytes" has been added to the 3.19.y-ckt tree Date: Mon, 11 Apr 2016 16:42:15 -0700 Message-Id: <1460418135-22339-1-git-send-email-kamal@canonical.com> X-Mailer: git-send-email 2.7.4 X-Extended-Stable: 3.19 Cc: Kamal Mostafa , Hannes Reinecke , Ewan Milne , kernel-team@lists.ubuntu.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com This is a note to let you know that I have just added a patch titled sd: Fix excessive capacity printing on devices with blocks bigger than 512 bytes to the linux-3.19.y-queue branch of the 3.19.y-ckt extended stable tree which can be found at: http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.19.y-queue This patch is scheduled to be released in version 3.19.8-ckt19. If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.19.y-ckt tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Kamal ---8<------------------------------------------------------------ From 33e09707097dec0c07caad7ff0c6475c22f896ba Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Mon, 28 Mar 2016 21:18:56 -0400 Subject: sd: Fix excessive capacity printing on devices with blocks bigger than 512 bytes commit f08bb1e0dbdd0297258d0b8cd4dbfcc057e57b2a upstream. During revalidate we check whether device capacity has changed before we decide whether to output disk information or not. The check for old capacity failed to take into account that we scaled sdkp->capacity based on the reported logical block size. And therefore the capacity test would always fail for devices with sectors bigger than 512 bytes and we would print several copies of the same discovery information. Avoid scaling sdkp->capacity and instead adjust the value on the fly when setting the block device capacity and generating fake C/H/S geometry. Signed-off-by: Martin K. Petersen Reported-by: Hannes Reinecke Reviewed-by: Hannes Reinicke Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen Signed-off-by: Kamal Mostafa --- drivers/scsi/sd.c | 23 ++++++++--------------- drivers/scsi/sd.h | 7 ++++++- 2 files changed, 14 insertions(+), 16 deletions(-) -- 2.7.4 diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index f780463..02f4bb5 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1281,18 +1281,19 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); struct scsi_device *sdp = sdkp->device; struct Scsi_Host *host = sdp->host; + sector_t capacity = logical_to_sectors(sdp, sdkp->capacity); int diskinfo[4]; /* default to most commonly used values */ - diskinfo[0] = 0x40; /* 1 << 6 */ - diskinfo[1] = 0x20; /* 1 << 5 */ - diskinfo[2] = sdkp->capacity >> 11; - + diskinfo[0] = 0x40; /* 1 << 6 */ + diskinfo[1] = 0x20; /* 1 << 5 */ + diskinfo[2] = capacity >> 11; + /* override with calculated, extended default, or driver values */ if (host->hostt->bios_param) - host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo); + host->hostt->bios_param(sdp, bdev, capacity, diskinfo); else - scsicam_bios_param(bdev, sdkp->capacity, diskinfo); + scsicam_bios_param(bdev, capacity, diskinfo); geo->heads = diskinfo[0]; geo->sectors = diskinfo[1]; @@ -2254,14 +2255,6 @@ got_data: } else sdkp->max_xfer_blocks = SD_DEF_XFER_BLOCKS; - /* Rescale capacity to 512-byte units */ - if (sector_size == 4096) - sdkp->capacity <<= 3; - else if (sector_size == 2048) - sdkp->capacity <<= 2; - else if (sector_size == 1024) - sdkp->capacity <<= 1; - blk_queue_physical_block_size(sdp->request_queue, sdkp->physical_block_size); sdkp->device->sector_size = sector_size; @@ -2797,7 +2790,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sdkp->disk->queue->limits.max_sectors = min_not_zero(queue_max_hw_sectors(sdkp->disk->queue), max_xfer); - set_capacity(disk, sdkp->capacity); + set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity)); sd_config_write_same(sdkp); kfree(buffer); diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 63ba5ca..0264936 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -65,7 +65,7 @@ struct scsi_disk { struct device dev; struct gendisk *disk; atomic_t openers; - sector_t capacity; /* size in 512-byte sectors */ + sector_t capacity; /* size in logical blocks */ u32 max_xfer_blocks; u32 max_ws_blocks; u32 max_unmap_blocks; @@ -145,6 +145,11 @@ static inline int scsi_medium_access_command(struct scsi_cmnd *scmd) return 0; } +static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blocks) +{ + return blocks << (ilog2(sdev->sector_size) - 9); +} + /* * A DIF-capable target device can be formatted with different * protection schemes. Currently 0 through 3 are defined: