Skip to content

Commit f08bb1e

Browse files
sd: Fix excessive capacity printing on devices with blocks bigger than 512 bytes
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 <martin.petersen@oracle.com> Cc: <stable@vger.kernel.org> Reported-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Hannes Reinicke <hare@suse.de> Reviewed-by: Ewan Milne <emilne@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 38c3159 commit f08bb1e

File tree

2 files changed

+14
-21
lines changed

2 files changed

+14
-21
lines changed

drivers/scsi/sd.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,18 +1275,19 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
12751275
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
12761276
struct scsi_device *sdp = sdkp->device;
12771277
struct Scsi_Host *host = sdp->host;
1278+
sector_t capacity = logical_to_sectors(sdp, sdkp->capacity);
12781279
int diskinfo[4];
12791280

12801281
/* default to most commonly used values */
1281-
diskinfo[0] = 0x40; /* 1 << 6 */
1282-
diskinfo[1] = 0x20; /* 1 << 5 */
1283-
diskinfo[2] = sdkp->capacity >> 11;
1284-
1282+
diskinfo[0] = 0x40; /* 1 << 6 */
1283+
diskinfo[1] = 0x20; /* 1 << 5 */
1284+
diskinfo[2] = capacity >> 11;
1285+
12851286
/* override with calculated, extended default, or driver values */
12861287
if (host->hostt->bios_param)
1287-
host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo);
1288+
host->hostt->bios_param(sdp, bdev, capacity, diskinfo);
12881289
else
1289-
scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
1290+
scsicam_bios_param(bdev, capacity, diskinfo);
12901291

12911292
geo->heads = diskinfo[0];
12921293
geo->sectors = diskinfo[1];
@@ -2337,14 +2338,6 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
23372338
if (sdkp->capacity > 0xffffffff)
23382339
sdp->use_16_for_rw = 1;
23392340

2340-
/* Rescale capacity to 512-byte units */
2341-
if (sector_size == 4096)
2342-
sdkp->capacity <<= 3;
2343-
else if (sector_size == 2048)
2344-
sdkp->capacity <<= 2;
2345-
else if (sector_size == 1024)
2346-
sdkp->capacity <<= 1;
2347-
23482341
blk_queue_physical_block_size(sdp->request_queue,
23492342
sdkp->physical_block_size);
23502343
sdkp->device->sector_size = sector_size;
@@ -2812,11 +2805,6 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp)
28122805
return 0;
28132806
}
28142807

2815-
static inline u32 logical_to_sectors(struct scsi_device *sdev, u32 blocks)
2816-
{
2817-
return blocks << (ilog2(sdev->sector_size) - 9);
2818-
}
2819-
28202808
/**
28212809
* sd_revalidate_disk - called the first time a new disk is seen,
28222810
* performs disk spin up, read_capacity, etc.
@@ -2900,7 +2888,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
29002888
/* Combine with controller limits */
29012889
q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
29022890

2903-
set_capacity(disk, sdkp->capacity);
2891+
set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
29042892
sd_config_write_same(sdkp);
29052893
kfree(buffer);
29062894

drivers/scsi/sd.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct scsi_disk {
6565
struct device dev;
6666
struct gendisk *disk;
6767
atomic_t openers;
68-
sector_t capacity; /* size in 512-byte sectors */
68+
sector_t capacity; /* size in logical blocks */
6969
u32 max_xfer_blocks;
7070
u32 opt_xfer_blocks;
7171
u32 max_ws_blocks;
@@ -146,6 +146,11 @@ static inline int scsi_medium_access_command(struct scsi_cmnd *scmd)
146146
return 0;
147147
}
148148

149+
static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blocks)
150+
{
151+
return blocks << (ilog2(sdev->sector_size) - 9);
152+
}
153+
149154
/*
150155
* A DIF-capable target device can be formatted with different
151156
* protection schemes. Currently 0 through 3 are defined:

0 commit comments

Comments
 (0)