* I/O Topology v3
@ 2009-05-15 4:40 Martin K. Petersen
2009-05-15 4:40 ` [PATCH 01/13] block: Do away with the notion of hardsect_size Martin K. Petersen
` (12 more replies)
0 siblings, 13 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Third take of the I/O topology patches. This time against Jens' 2.6.31
tree.
Changes:
- Remove the notion of hardsect_size as it about to become a confusing
anachronism. Use logical_block_size to refer to the block size used
when talking to the device via ATA/SCSI.
- Use the term physical_block_size to refer to the device physical
sector size.
(Logical and physical are the terms used in the T10/T13 standards).
- Move queue limits to an embedded struct so DM can get rid of its
internal I/O restriction housekeeping and use the same stacking
function as MD.
- Switch MD to new stacking API. Once MD has been updated, the old
stacking function can be removed.
Block layer topology enablement:
0001-block-Do-away-with-the-notion-of-hardsect_size.patch
0002-block-Use-accessor-functions-for-queue-limits.patch
0003-block-Move-queue-limits-to-an-embedded-struct.patch
0004-block-Expose-stacked-device-queues-in-sysfs.patch
0005-block-Export-I-O-topology-for-block-devices-and-par.patch
Post merge:
0006-MD-Use-new-topology-calls-to-indicate-alignment-and.patch
0007-block-Deprecate-blk_queue_stack_limits.patch
0008-sd-Physical-block-size-and-alignment-support.patch
0009-sd-Detect-non-rotational-devices.patch
0010-sd-Block-limits-VPD-support.patch
Independent:
0011-scsi_debug-Add-support-for-physical-block-exponent.patch
0012-libata-Report-disk-alignment-and-physical-block-siz.patch
0013-libata-Media-rotation-rate-and-form-factor-heuristi.patch
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 01/13] block: Do away with the notion of hardsect_size
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 02/13] block: Use accessor functions for queue limits Martin K. Petersen
` (11 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Until now we have had a 1:1 mapping between storage device physical
block size and the logical block sized used when addressing the device.
With SATA 4KB drives coming out that will no longer be the case. The
sector size will be 4KB but the logical block size will remain
512-bytes. Hence we need to distinguish between the physical block size
and the logical ditto.
This patch renames hardsect_size to logical_block_size.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
arch/powerpc/sysdev/axonram.c | 2 +-
block/blk-integrity.c | 2 +-
block/blk-settings.c | 21 ++++++++++-----------
block/blk-sysfs.c | 12 +++++++++---
block/compat_ioctl.c | 2 +-
block/ioctl.c | 2 +-
drivers/block/cciss.c | 6 +++---
drivers/block/cpqarray.c | 4 ++--
drivers/block/hd.c | 2 +-
drivers/block/mg_disk.c | 2 +-
drivers/block/pktcdvd.c | 2 +-
drivers/block/ps3disk.c | 2 +-
drivers/block/ub.c | 6 +++---
drivers/block/virtio_blk.c | 2 +-
drivers/block/xen-blkfront.c | 2 +-
drivers/block/xsysace.c | 2 +-
drivers/cdrom/gdrom.c | 2 +-
drivers/cdrom/viocd.c | 4 ++--
drivers/char/raw.c | 2 +-
drivers/ide/ide-cd.c | 12 ++++++------
drivers/md/bitmap.c | 4 ++--
drivers/md/dm-exception-store.c | 2 +-
drivers/md/dm-log.c | 3 ++-
drivers/md/dm-snap-persistent.c | 2 +-
drivers/md/dm-table.c | 12 +++++++-----
drivers/md/md.c | 2 +-
drivers/memstick/core/mspro_block.c | 2 +-
drivers/message/i2o/i2o_block.c | 5 +++--
drivers/mmc/card/block.c | 2 +-
drivers/mtd/mtd_blkdevs.c | 2 +-
drivers/s390/block/dasd.c | 2 +-
drivers/s390/block/dcssblk.c | 2 +-
drivers/s390/block/xpram.c | 2 +-
drivers/s390/char/tape_block.c | 2 +-
drivers/scsi/sd.c | 2 +-
drivers/scsi/sr.c | 2 +-
fs/bio.c | 3 ++-
fs/block_dev.c | 6 +++---
fs/buffer.c | 6 +++---
fs/direct-io.c | 2 +-
fs/ext3/super.c | 4 ++--
fs/ext4/super.c | 2 +-
fs/gfs2/ops_fstype.c | 4 ++--
fs/gfs2/rgrp.c | 2 +-
fs/nilfs2/the_nilfs.c | 2 +-
fs/ntfs/super.c | 6 +++---
fs/ocfs2/cluster/heartbeat.c | 2 +-
fs/ocfs2/super.c | 2 +-
fs/partitions/ibm.c | 2 +-
fs/partitions/msdos.c | 4 ++--
fs/udf/super.c | 2 +-
fs/xfs/linux-2.6/xfs_buf.c | 2 +-
include/linux/blkdev.h | 14 +++++++-------
include/linux/device-mapper.h | 2 +-
54 files changed, 108 insertions(+), 98 deletions(-)
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index 9e105cb..a477991 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -250,7 +250,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
set_capacity(bank->disk, bank->size >> AXON_RAM_SECTOR_SHIFT);
blk_queue_make_request(bank->disk->queue, axon_ram_make_request);
- blk_queue_hardsect_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE);
+ blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE);
add_disk(bank->disk);
bank->irq_id = irq_of_parse_and_map(device->node, 0);
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 91fa8e0..73e28d3 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -340,7 +340,7 @@ int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template)
kobject_uevent(&bi->kobj, KOBJ_ADD);
bi->flags |= INTEGRITY_FLAG_READ | INTEGRITY_FLAG_WRITE;
- bi->sector_size = disk->queue->hardsect_size;
+ bi->sector_size = queue_logical_block_size(disk->queue);
disk->integrity = bi;
} else
bi = disk->integrity;
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 57af728..15c3164 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -134,7 +134,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
q->backing_dev_info.state = 0;
q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
- blk_queue_hardsect_size(q, 512);
+ blk_queue_logical_block_size(q, 512);
blk_queue_dma_alignment(q, 511);
blk_queue_congestion_threshold(q);
q->nr_batching = BLK_BATCH_REQ;
@@ -288,21 +288,20 @@ void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size)
EXPORT_SYMBOL(blk_queue_max_segment_size);
/**
- * blk_queue_hardsect_size - set hardware sector size for the queue
+ * blk_queue_logical_block_size - set logical block size for the queue
* @q: the request queue for the device
- * @size: the hardware sector size, in bytes
+ * @size: the logical block size, in bytes
*
* Description:
- * This should typically be set to the lowest possible sector size
- * that the hardware can operate on (possible without reverting to
- * even internal read-modify-write operations). Usually the default
- * of 512 covers most hardware.
+ * This should be set to the lowest possible block size that the
+ * storage device can address. The default of 512 covers most
+ * hardware.
**/
-void blk_queue_hardsect_size(struct request_queue *q, unsigned short size)
+void blk_queue_logical_block_size(struct request_queue *q, unsigned short size)
{
- q->hardsect_size = size;
+ q->logical_block_size = size;
}
-EXPORT_SYMBOL(blk_queue_hardsect_size);
+EXPORT_SYMBOL(blk_queue_logical_block_size);
/*
* Returns the minimum that is _not_ zero, unless both are zero.
@@ -324,7 +323,7 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
t->max_phys_segments = min_not_zero(t->max_phys_segments, b->max_phys_segments);
t->max_hw_segments = min_not_zero(t->max_hw_segments, b->max_hw_segments);
t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size);
- t->hardsect_size = max(t->hardsect_size, b->hardsect_size);
+ t->logical_block_size = max(t->logical_block_size, b->logical_block_size);
if (!t->queue_lock)
WARN_ON_ONCE(1);
else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 3ff9bba..13d38b7 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -100,9 +100,9 @@ static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
return queue_var_show(max_sectors_kb, (page));
}
-static ssize_t queue_hw_sector_size_show(struct request_queue *q, char *page)
+static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
{
- return queue_var_show(q->hardsect_size, page);
+ return queue_var_show(queue_logical_block_size(q), page);
}
static ssize_t
@@ -249,7 +249,12 @@ static struct queue_sysfs_entry queue_iosched_entry = {
static struct queue_sysfs_entry queue_hw_sector_size_entry = {
.attr = {.name = "hw_sector_size", .mode = S_IRUGO },
- .show = queue_hw_sector_size_show,
+ .show = queue_logical_block_size_show,
+};
+
+static struct queue_sysfs_entry queue_logical_block_size_entry = {
+ .attr = {.name = "logical_block_size", .mode = S_IRUGO },
+ .show = queue_logical_block_size_show,
};
static struct queue_sysfs_entry queue_nonrot_entry = {
@@ -283,6 +288,7 @@ static struct attribute *default_attrs[] = {
&queue_max_sectors_entry.attr,
&queue_iosched_entry.attr,
&queue_hw_sector_size_entry.attr,
+ &queue_logical_block_size_entry.attr,
&queue_nonrot_entry.attr,
&queue_nomerges_entry.attr,
&queue_rq_affinity_entry.attr,
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f87615d..9eaa194 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -763,7 +763,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
return compat_put_int(arg, block_size(bdev));
case BLKSSZGET: /* get block device hardware sector size */
- return compat_put_int(arg, bdev_hardsect_size(bdev));
+ return compat_put_int(arg, bdev_logical_block_size(bdev));
case BLKSECTGET:
return compat_put_ushort(arg,
bdev_get_queue(bdev)->max_sectors);
diff --git a/block/ioctl.c b/block/ioctl.c
index ad474d4..7aa97f6 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -311,7 +311,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
return put_int(arg, block_size(bdev));
case BLKSSZGET: /* get block device hardware sector size */
- return put_int(arg, bdev_hardsect_size(bdev));
+ return put_int(arg, bdev_logical_block_size(bdev));
case BLKSECTGET:
return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
case BLKRASET:
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index e714e7c..94474f5 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1389,8 +1389,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
disk->queue->queuedata = h;
- blk_queue_hardsect_size(disk->queue,
- h->drv[drv_index].block_size);
+ blk_queue_logical_block_size(disk->queue,
+ h->drv[drv_index].block_size);
/* Make sure all queue data is written out before */
/* setting h->drv[drv_index].queue, as setting this */
@@ -2298,7 +2298,7 @@ static int cciss_revalidate(struct gendisk *disk)
cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size,
inq_buff, drv);
- blk_queue_hardsect_size(drv->queue, drv->block_size);
+ blk_queue_logical_block_size(drv->queue, drv->block_size);
set_capacity(disk, drv->nr_blocks);
kfree(inq_buff);
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index a02dcfc..44fa201 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -474,7 +474,7 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev)
disk->fops = &ida_fops;
if (j && !drv->nr_blks)
continue;
- blk_queue_hardsect_size(hba[i]->queue, drv->blk_size);
+ blk_queue_logical_block_size(hba[i]->queue, drv->blk_size);
set_capacity(disk, drv->nr_blks);
disk->queue = hba[i]->queue;
disk->private_data = drv;
@@ -1546,7 +1546,7 @@ static int revalidate_allvol(ctlr_info_t *host)
drv_info_t *drv = &host->drv[i];
if (i && !drv->nr_blks)
continue;
- blk_queue_hardsect_size(host->queue, drv->blk_size);
+ blk_queue_logical_block_size(host->queue, drv->blk_size);
set_capacity(disk, drv->nr_blks);
disk->queue = host->queue;
disk->private_data = drv;
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 961de56..f65b3f3 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -724,7 +724,7 @@ static int __init hd_init(void)
blk_queue_max_sectors(hd_queue, 255);
init_timer(&device_timer);
device_timer.function = hd_times_out;
- blk_queue_hardsect_size(hd_queue, 512);
+ blk_queue_logical_block_size(hd_queue, 512);
if (!NR_HD) {
/*
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index c0cd0a0..60de5a0 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -996,7 +996,7 @@ static int mg_probe(struct platform_device *plat_dev)
goto probe_err_6;
}
blk_queue_max_sectors(host->breq, MG_MAX_SECTS);
- blk_queue_hardsect_size(host->breq, MG_SECTOR_SIZE);
+ blk_queue_logical_block_size(host->breq, MG_SECTOR_SIZE);
init_timer(&host->timer);
host->timer.function = mg_times_out;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index dc7a8c3..293f585 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2657,7 +2657,7 @@ static void pkt_init_queue(struct pktcdvd_device *pd)
struct request_queue *q = pd->disk->queue;
blk_queue_make_request(q, pkt_make_request);
- blk_queue_hardsect_size(q, CD_FRAMESIZE);
+ blk_queue_logical_block_size(q, CD_FRAMESIZE);
blk_queue_max_sectors(q, PACKET_MAX_SECTORS);
blk_queue_merge_bvec(q, pkt_merge_bvec);
q->queuedata = pd;
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 338cee4..aaeeb54 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -477,7 +477,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
blk_queue_max_sectors(queue, dev->bounce_size >> 9);
blk_queue_segment_boundary(queue, -1UL);
blk_queue_dma_alignment(queue, dev->blk_size-1);
- blk_queue_hardsect_size(queue, dev->blk_size);
+ blk_queue_logical_block_size(queue, dev->blk_size);
blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
ps3disk_prepare_flush);
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 178f459..917c161 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -723,7 +723,7 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
/*
* build the command
*
- * The call to blk_queue_hardsect_size() guarantees that request
+ * The call to blk_queue_logical_block_size() guarantees that request
* is aligned, but it is given in terms of 512 byte units, always.
*/
block = blk_rq_pos(rq) >> lun->capacity.bshift;
@@ -1757,7 +1757,7 @@ static int ub_bd_revalidate(struct gendisk *disk)
ub_revalidate(lun->udev, lun);
/* XXX Support sector size switching like in sr.c */
- blk_queue_hardsect_size(disk->queue, lun->capacity.bsize);
+ blk_queue_logical_block_size(disk->queue, lun->capacity.bsize);
set_capacity(disk, lun->capacity.nsec);
// set_disk_ro(sdkp->disk, lun->readonly);
@@ -2332,7 +2332,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
blk_queue_max_phys_segments(q, UB_MAX_REQ_SG);
blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */
blk_queue_max_sectors(q, UB_MAX_SECTORS);
- blk_queue_hardsect_size(q, lun->capacity.bsize);
+ blk_queue_logical_block_size(q, lun->capacity.bsize);
lun->disk = disk;
q->queuedata = lun;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 29a9daf..89603c4 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -313,7 +313,7 @@ static int virtblk_probe(struct virtio_device *vdev)
offsetof(struct virtio_blk_config, blk_size),
&blk_size);
if (!err)
- blk_queue_hardsect_size(vblk->disk->queue, blk_size);
+ blk_queue_logical_block_size(vblk->disk->queue, blk_size);
add_disk(vblk->disk);
return 0;
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 6d4ac76..074b1b9 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -344,7 +344,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
/* Hard sector size and max sectors impersonate the equiv. hardware. */
- blk_queue_hardsect_size(rq, sector_size);
+ blk_queue_logical_block_size(rq, sector_size);
blk_queue_max_sectors(rq, 512);
/* Each segment in a request is up to an aligned page in size. */
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 3a4397e..f08491a 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -984,7 +984,7 @@ static int __devinit ace_setup(struct ace_device *ace)
ace->queue = blk_init_queue(ace_request, &ace->lock);
if (ace->queue == NULL)
goto err_blk_initq;
- blk_queue_hardsect_size(ace->queue, 512);
+ blk_queue_logical_block_size(ace->queue, 512);
/*
* Allocate and initialize GD structure
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 1e366ad..b5621f2 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -739,7 +739,7 @@ static void __devinit probe_gdrom_setupdisk(void)
static int __devinit probe_gdrom_setupqueue(void)
{
- blk_queue_hardsect_size(gd.gdrom_rq, GDROM_HARD_SECTOR);
+ blk_queue_logical_block_size(gd.gdrom_rq, GDROM_HARD_SECTOR);
/* using DMA so memory will need to be contiguous */
blk_queue_max_hw_segments(gd.gdrom_rq, 1);
/* set a large max size to get most from DMA */
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index ca741c2..fb11651 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -469,8 +469,8 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
case viocdopen:
if (event->xRc == 0) {
di = &viocd_diskinfo[bevent->disk];
- blk_queue_hardsect_size(di->viocd_disk->queue,
- bevent->block_size);
+ blk_queue_logical_block_size(di->viocd_disk->queue,
+ bevent->block_size);
set_capacity(di->viocd_disk,
bevent->media_size *
bevent->block_size / 512);
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 20d90e6..db32f0e 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -71,7 +71,7 @@ static int raw_open(struct inode *inode, struct file *filp)
err = bd_claim(bdev, raw_open);
if (err)
goto out1;
- err = set_blocksize(bdev, bdev_hardsect_size(bdev));
+ err = set_blocksize(bdev, bdev_logical_block_size(bdev));
if (err)
goto out2;
filp->f_flags |= O_DIRECT;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 4c7792f..03b43e0 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -182,7 +182,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
(sense->information[2] << 8) |
(sense->information[3]);
- if (drive->queue->hardsect_size == 2048)
+ if (queue_logical_block_size(drive->queue) == 2048)
/* device sector size is 2K */
sector <<= 2;
@@ -738,7 +738,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
- queue_hardsect_size(q) >> SECTOR_BITS;
+ queue_logical_block_size(q) >> SECTOR_BITS;
ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
"secs_per_frame: %u",
@@ -1022,8 +1022,8 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* save a private copy of the TOC capacity for error handling */
drive->probed_capacity = toc->capacity * sectors_per_frame;
- blk_queue_hardsect_size(drive->queue,
- sectors_per_frame << SECTOR_BITS);
+ blk_queue_logical_block_size(drive->queue,
+ sectors_per_frame << SECTOR_BITS);
/* first read just the header, so we know how long the TOC is */
stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
@@ -1339,7 +1339,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
/* standard prep_rq_fn that builds 10 byte cmds */
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
{
- int hard_sect = queue_hardsect_size(q);
+ int hard_sect = queue_logical_block_size(q);
long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
@@ -1544,7 +1544,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities(drive);
- blk_queue_hardsect_size(q, CD_FRAMESIZE);
+ blk_queue_logical_block_size(q, CD_FRAMESIZE);
if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR PFX "%s: %s failed to register device with the"
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 1fb91ed..4f7e985 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -232,7 +232,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset,
target = rdev->sb_start + offset + index * (PAGE_SIZE/512);
if (sync_page_io(rdev->bdev, target,
- roundup(size, bdev_hardsect_size(rdev->bdev)),
+ roundup(size, bdev_logical_block_size(rdev->bdev)),
page, READ)) {
page->index = index;
attach_page_buffers(page, NULL); /* so that free_buffer will
@@ -287,7 +287,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
int size = PAGE_SIZE;
if (page->index == bitmap->file_pages-1)
size = roundup(bitmap->last_page_size,
- bdev_hardsect_size(rdev->bdev));
+ bdev_logical_block_size(rdev->bdev));
/* Just make sure we aren't corrupting data or
* metadata
*/
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index a2e26c2..75d8081 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -178,7 +178,7 @@ static int set_chunk_size(struct dm_exception_store *store,
}
/* Validate the chunk size against the device block size */
- if (chunk_size_ulong % (bdev_hardsect_size(store->cow->bdev) >> 9)) {
+ if (chunk_size_ulong % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
*error = "Chunk size is not a multiple of device blocksize";
return -EINVAL;
}
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index be233bc..6fa8ccf 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -413,7 +413,8 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
* Buffer holds both header and bitset.
*/
buf_size = dm_round_up((LOG_OFFSET << SECTOR_SHIFT) +
- bitset_size, ti->limits.hardsect_size);
+ bitset_size,
+ ti->limits.logical_block_size);
if (buf_size > dev->bdev->bd_inode->i_size) {
DMWARN("log device %s too small: need %llu bytes",
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index e75c6dd..2662a41 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -282,7 +282,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
*/
if (!ps->store->chunk_size) {
ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
- bdev_hardsect_size(ps->store->cow->bdev) >> 9);
+ bdev_logical_block_size(ps->store->cow->bdev) >> 9);
ps->store->chunk_mask = ps->store->chunk_size - 1;
ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
chunk_size_supplied = 0;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 429b50b..65e2d97 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -108,7 +108,8 @@ static void combine_restrictions_low(struct io_restrictions *lhs,
lhs->max_hw_segments =
min_not_zero(lhs->max_hw_segments, rhs->max_hw_segments);
- lhs->hardsect_size = max(lhs->hardsect_size, rhs->hardsect_size);
+ lhs->logical_block_size = max(lhs->logical_block_size,
+ rhs->logical_block_size);
lhs->max_segment_size =
min_not_zero(lhs->max_segment_size, rhs->max_segment_size);
@@ -529,7 +530,8 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
rs->max_hw_segments =
min_not_zero(rs->max_hw_segments, q->max_hw_segments);
- rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size);
+ rs->logical_block_size = max(rs->logical_block_size,
+ queue_logical_block_size(q));
rs->max_segment_size =
min_not_zero(rs->max_segment_size, q->max_segment_size);
@@ -683,8 +685,8 @@ static void check_for_valid_limits(struct io_restrictions *rs)
rs->max_phys_segments = MAX_PHYS_SEGMENTS;
if (!rs->max_hw_segments)
rs->max_hw_segments = MAX_HW_SEGMENTS;
- if (!rs->hardsect_size)
- rs->hardsect_size = 1 << SECTOR_SHIFT;
+ if (!rs->logical_block_size)
+ rs->logical_block_size = 1 << SECTOR_SHIFT;
if (!rs->max_segment_size)
rs->max_segment_size = MAX_SEGMENT_SIZE;
if (!rs->seg_boundary_mask)
@@ -914,7 +916,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
blk_queue_max_sectors(q, t->limits.max_sectors);
q->max_phys_segments = t->limits.max_phys_segments;
q->max_hw_segments = t->limits.max_hw_segments;
- q->hardsect_size = t->limits.hardsect_size;
+ q->logical_block_size = t->limits.logical_block_size;
q->max_segment_size = t->limits.max_segment_size;
q->max_hw_sectors = t->limits.max_hw_sectors;
q->seg_boundary_mask = t->limits.seg_boundary_mask;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 612343f..7f9d58f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1202,7 +1202,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read));
rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
- bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
+ bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1;
if (rdev->sb_size & bmask)
rdev->sb_size = (rdev->sb_size | bmask) + 1;
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index c0bebc6..7847bbc 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1242,7 +1242,7 @@ static int mspro_block_init_disk(struct memstick_dev *card)
sprintf(msb->disk->disk_name, "mspblk%d", disk_id);
- blk_queue_hardsect_size(msb->queue, msb->page_size);
+ blk_queue_logical_block_size(msb->queue, msb->page_size);
capacity = be16_to_cpu(sys_info->user_block_count);
capacity *= be16_to_cpu(sys_info->block_size);
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 6573ef4..335d4c7 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -794,8 +794,9 @@ static int i2o_block_transfer(struct request *req)
if (c->adaptec) {
u8 cmd[10];
u32 scsi_flags;
- u16 hwsec = queue_hardsect_size(req->q) >> KERNEL_SECTOR_SHIFT;
+ u16 hwsec;
+ hwsec = queue_logical_block_size(req->q) >> KERNEL_SECTOR_SHIFT;
memset(cmd, 0, 10);
sgl_offset = SGL_OFFSET_12;
@@ -1078,7 +1079,7 @@ static int i2o_block_probe(struct device *dev)
*/
if (!i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
!i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
- blk_queue_hardsect_size(queue, le32_to_cpu(blocksize));
+ blk_queue_logical_block_size(queue, le32_to_cpu(blocksize));
} else
osm_warn("unable to get blocksize of %s\n", gd->disk_name);
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 949e997..2f6703d 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -513,7 +513,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
sprintf(md->disk->disk_name, "mmcblk%d", devidx);
- blk_queue_hardsect_size(md->queue.queue, 512);
+ blk_queue_logical_block_size(md->queue.queue, 512);
if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
/*
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 502622f..aaac3b6 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -378,7 +378,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
}
tr->blkcore_priv->rq->queuedata = tr;
- blk_queue_hardsect_size(tr->blkcore_priv->rq, tr->blksize);
+ blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize);
if (tr->discard)
blk_queue_set_discard(tr->blkcore_priv->rq,
blktrans_discard_request);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index e64f62d..27a1be0 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1990,7 +1990,7 @@ static void dasd_setup_queue(struct dasd_block *block)
{
int max;
- blk_queue_hardsect_size(block->request_queue, block->bp_block);
+ blk_queue_logical_block_size(block->request_queue, block->bp_block);
max = block->base->discipline->max_blocks << block->s2b_shift;
blk_queue_max_sectors(block->request_queue, max);
blk_queue_max_phys_segments(block->request_queue, -1L);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index cfdcf1a..a4c7ffc 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -602,7 +602,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
dev_info->gd->private_data = dev_info;
dev_info->gd->driverfs_dev = &dev_info->dev;
blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request);
- blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096);
+ blk_queue_logical_block_size(dev_info->dcssblk_queue, 4096);
seg_byte_size = (dev_info->end - dev_info->start + 1);
set_capacity(dev_info->gd, seg_byte_size >> 9); // size in sectors
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 76814f3..0ae0c83 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -343,7 +343,7 @@ static int __init xpram_setup_blkdev(void)
goto out;
}
blk_queue_make_request(xpram_queues[i], xpram_make_request);
- blk_queue_hardsect_size(xpram_queues[i], 4096);
+ blk_queue_logical_block_size(xpram_queues[i], 4096);
}
/*
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 1e79676..47ff695 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -222,7 +222,7 @@ tapeblock_setup_device(struct tape_device * device)
if (rc)
goto cleanup_queue;
- blk_queue_hardsect_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE);
+ blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE);
blk_queue_max_sectors(blkdat->request_queue, TAPEBLOCK_MAX_SEC);
blk_queue_max_phys_segments(blkdat->request_queue, -1L);
blk_queue_max_hw_segments(blkdat->request_queue, -1L);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 70c4dd9..c3afcae 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1515,7 +1515,7 @@ got_data:
*/
sector_size = 512;
}
- blk_queue_hardsect_size(sdp->request_queue, sector_size);
+ blk_queue_logical_block_size(sdp->request_queue, sector_size);
{
char cap_str_2[10], cap_str_10[10];
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index fddba53..cd350df 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -727,7 +727,7 @@ static void get_sectorsize(struct scsi_cd *cd)
}
queue = cd->device->request_queue;
- blk_queue_hardsect_size(queue, sector_size);
+ blk_queue_logical_block_size(queue, sector_size);
return;
}
diff --git a/fs/bio.c b/fs/bio.c
index 7bbc98f..28f9f17 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1487,11 +1487,12 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
sector_t bio_sector_offset(struct bio *bio, unsigned short index,
unsigned int offset)
{
- unsigned int sector_sz = queue_hardsect_size(bio->bi_bdev->bd_disk->queue);
+ unsigned int sector_sz;
struct bio_vec *bv;
sector_t sectors;
int i;
+ sector_sz = queue_logical_block_size(bio->bi_bdev->bd_disk->queue);
sectors = 0;
if (index >= bio->bi_idx)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index a85fe31..a29b4dc 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -76,7 +76,7 @@ int set_blocksize(struct block_device *bdev, int size)
return -EINVAL;
/* Size cannot be smaller than the size supported by the device */
- if (size < bdev_hardsect_size(bdev))
+ if (size < bdev_logical_block_size(bdev))
return -EINVAL;
/* Don't change the size if it is same as current */
@@ -106,7 +106,7 @@ EXPORT_SYMBOL(sb_set_blocksize);
int sb_min_blocksize(struct super_block *sb, int size)
{
- int minsize = bdev_hardsect_size(sb->s_bdev);
+ int minsize = bdev_logical_block_size(sb->s_bdev);
if (size < minsize)
size = minsize;
return sb_set_blocksize(sb, size);
@@ -1117,7 +1117,7 @@ EXPORT_SYMBOL(check_disk_change);
void bd_set_size(struct block_device *bdev, loff_t size)
{
- unsigned bsize = bdev_hardsect_size(bdev);
+ unsigned bsize = bdev_logical_block_size(bdev);
bdev->bd_inode->i_size = size;
while (bsize < PAGE_CACHE_SIZE) {
diff --git a/fs/buffer.c b/fs/buffer.c
index b3e5be7..405086a 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1085,12 +1085,12 @@ static struct buffer_head *
__getblk_slow(struct block_device *bdev, sector_t block, int size)
{
/* Size must be multiple of hard sectorsize */
- if (unlikely(size & (bdev_hardsect_size(bdev)-1) ||
+ if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
(size < 512 || size > PAGE_SIZE))) {
printk(KERN_ERR "getblk(): invalid block size %d requested\n",
size);
- printk(KERN_ERR "hardsect size: %d\n",
- bdev_hardsect_size(bdev));
+ printk(KERN_ERR "logical block size: %d\n",
+ bdev_logical_block_size(bdev));
dump_stack();
return NULL;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 05763bb..8b10b87 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1127,7 +1127,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
rw = WRITE_ODIRECT;
if (bdev)
- bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
+ bdev_blkbits = blksize_bits(bdev_logical_block_size(bdev));
if (offset & blocksize_mask) {
if (bdev)
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 599dbfe..acbb94f 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1696,7 +1696,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
goto failed_mount;
}
- hblock = bdev_hardsect_size(sb->s_bdev);
+ hblock = bdev_logical_block_size(sb->s_bdev);
if (sb->s_blocksize != blocksize) {
/*
* Make sure the blocksize for the filesystem is larger
@@ -2119,7 +2119,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb,
}
blocksize = sb->s_blocksize;
- hblock = bdev_hardsect_size(bdev);
+ hblock = bdev_logical_block_size(bdev);
if (blocksize < hblock) {
printk(KERN_ERR
"EXT3-fs: blocksize too small for journal device.\n");
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2958f4e..a30549f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2962,7 +2962,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
}
blocksize = sb->s_blocksize;
- hblock = bdev_hardsect_size(bdev);
+ hblock = bdev_logical_block_size(bdev);
if (blocksize < hblock) {
printk(KERN_ERR
"EXT4-fs: blocksize too small for journal device.\n");
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 650a730..5e53716 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -526,11 +526,11 @@ static int init_sb(struct gfs2_sbd *sdp, int silent)
}
/* Set up the buffer cache and SB for real */
- if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) {
+ if (sdp->sd_sb.sb_bsize < bdev_logical_block_size(sb->s_bdev)) {
ret = -EINVAL;
fs_err(sdp, "FS block size (%u) is too small for device "
"block size (%u)\n",
- sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));
+ sdp->sd_sb.sb_bsize, bdev_logical_block_size(sb->s_bdev));
goto out;
}
if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 5650382..a971d24 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -845,7 +845,7 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
struct super_block *sb = sdp->sd_vfs;
struct block_device *bdev = sb->s_bdev;
const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize /
- bdev_hardsect_size(sb->s_bdev);
+ bdev_logical_block_size(sb->s_bdev);
u64 blk;
sector_t start = 0;
sector_t nr_sects = 0;
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 7f65b3b..a91f15b 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -515,7 +515,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
if (sb->s_blocksize != blocksize) {
- int hw_blocksize = bdev_hardsect_size(sb->s_bdev);
+ int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
if (blocksize < hw_blocksize) {
printk(KERN_ERR
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index f76951d..6aa7c47 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
-#include <linux/blkdev.h> /* For bdev_hardsect_size(). */
+#include <linux/blkdev.h> /* For bdev_logical_block_size(). */
#include <linux/backing-dev.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
@@ -2785,13 +2785,13 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
goto err_out_now;
/* We support sector sizes up to the PAGE_CACHE_SIZE. */
- if (bdev_hardsect_size(sb->s_bdev) > PAGE_CACHE_SIZE) {
+ if (bdev_logical_block_size(sb->s_bdev) > PAGE_CACHE_SIZE) {
if (!silent)
ntfs_error(sb, "Device has unsupported sector size "
"(%i). The maximum supported sector "
"size on this architecture is %lu "
"bytes.",
- bdev_hardsect_size(sb->s_bdev),
+ bdev_logical_block_size(sb->s_bdev),
PAGE_CACHE_SIZE);
goto err_out_now;
}
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 4f85ece..09cc25d 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1371,7 +1371,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
bdevname(reg->hr_bdev, reg->hr_dev_name);
- sectsize = bdev_hardsect_size(reg->hr_bdev);
+ sectsize = bdev_logical_block_size(reg->hr_bdev);
if (sectsize != reg->hr_block_bytes) {
mlog(ML_ERROR,
"blocksize %u incorrect for device, expected %d",
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 79ff8d9..5c6163f 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -713,7 +713,7 @@ static int ocfs2_sb_probe(struct super_block *sb,
*bh = NULL;
/* may be > 512 */
- *sector_size = bdev_hardsect_size(sb->s_bdev);
+ *sector_size = bdev_logical_block_size(sb->s_bdev);
if (*sector_size > OCFS2_MAX_BLOCKSIZE) {
mlog(ML_ERROR, "Hardware sector size too large: %d (max=%d)\n",
*sector_size, OCFS2_MAX_BLOCKSIZE);
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 4629768..fc71aab 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -76,7 +76,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
Sector sect;
res = 0;
- blocksize = bdev_hardsect_size(bdev);
+ blocksize = bdev_logical_block_size(bdev);
if (blocksize <= 0)
goto out_exit;
i_size = i_size_read(bdev->bd_inode);
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 7965118..0028d2e 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -110,7 +110,7 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,
Sector sect;
unsigned char *data;
u32 this_sector, this_size;
- int sector_size = bdev_hardsect_size(bdev) / 512;
+ int sector_size = bdev_logical_block_size(bdev) / 512;
int loopct = 0; /* number of links followed
without finding a data partition */
int i;
@@ -415,7 +415,7 @@ static struct {
int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
{
- int sector_size = bdev_hardsect_size(bdev) / 512;
+ int sector_size = bdev_logical_block_size(bdev) / 512;
Sector sect;
unsigned char *data;
struct partition *p;
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 72348cc..0ba4410 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1915,7 +1915,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) {
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
} else {
- uopt.blocksize = bdev_hardsect_size(sb->s_bdev);
+ uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) {
if (!silent)
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index e28800a..1418b91 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1501,7 +1501,7 @@ xfs_setsize_buftarg_early(
struct block_device *bdev)
{
return xfs_setsize_buftarg_flags(btp,
- PAGE_CACHE_SIZE, bdev_hardsect_size(bdev), 0);
+ PAGE_CACHE_SIZE, bdev_logical_block_size(bdev), 0);
}
int
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index f9d60a7..85c7f7d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -391,7 +391,7 @@ struct request_queue
unsigned int max_hw_sectors;
unsigned short max_phys_segments;
unsigned short max_hw_segments;
- unsigned short hardsect_size;
+ unsigned short logical_block_size;
unsigned int max_segment_size;
unsigned long seg_boundary_mask;
@@ -899,7 +899,7 @@ extern void blk_queue_max_sectors(struct request_queue *, unsigned int);
extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
-extern void blk_queue_hardsect_size(struct request_queue *, unsigned short);
+extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
extern void blk_queue_dma_pad(struct request_queue *, unsigned int);
extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int);
@@ -986,19 +986,19 @@ extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
#define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
-static inline int queue_hardsect_size(struct request_queue *q)
+static inline unsigned short queue_logical_block_size(struct request_queue *q)
{
int retval = 512;
- if (q && q->hardsect_size)
- retval = q->hardsect_size;
+ if (q && q->logical_block_size)
+ retval = q->logical_block_size;
return retval;
}
-static inline int bdev_hardsect_size(struct block_device *bdev)
+static inline unsigned short bdev_logical_block_size(struct block_device *bdev)
{
- return queue_hardsect_size(bdev_get_queue(bdev));
+ return queue_logical_block_size(bdev_get_queue(bdev));
}
static inline int queue_dma_alignment(struct request_queue *q)
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index ded2d7c..49c2362 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -149,7 +149,7 @@ struct io_restrictions {
unsigned max_hw_sectors;
unsigned max_sectors;
unsigned max_segment_size;
- unsigned short hardsect_size;
+ unsigned short logical_block_size;
unsigned short max_hw_segments;
unsigned short max_phys_segments;
unsigned char no_cluster; /* inverted so that 0 is default */
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 02/13] block: Use accessor functions for queue limits
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
2009-05-15 4:40 ` [PATCH 01/13] block: Do away with the notion of hardsect_size Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-31 15:51 ` Bartlomiej Zolnierkiewicz
2009-05-15 4:40 ` [PATCH 03/13] block: Move queue limits to an embedded struct Martin K. Petersen
` (10 subsequent siblings)
12 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Convert all external users of queue limits to using wrapper functions
instead of poking the request queue variables directly.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
block/blk-barrier.c | 8 ++++----
block/blk-core.c | 16 ++++++++--------
block/blk-map.c | 4 ++--
block/blk-merge.c | 27 ++++++++++++++-------------
block/blk-settings.c | 15 ++++++++++++---
block/blk-sysfs.c | 8 ++++----
block/compat_ioctl.c | 2 +-
block/ioctl.c | 10 +++++-----
block/scsi_ioctl.c | 8 ++++----
drivers/block/pktcdvd.c | 6 ++++--
drivers/cdrom/cdrom.c | 4 ++--
drivers/md/dm-table.c | 28 ++++++++++++++--------------
drivers/md/linear.c | 2 +-
drivers/md/multipath.c | 4 ++--
drivers/md/raid0.c | 2 +-
drivers/md/raid1.c | 4 ++--
drivers/md/raid10.c | 8 ++++----
drivers/md/raid5.c | 4 ++--
drivers/scsi/sg.c | 15 ++++++++-------
drivers/scsi/st.c | 4 ++--
drivers/usb/storage/scsiglue.c | 4 ++--
fs/bio.c | 19 ++++++++++---------
include/linux/bio.h | 2 +-
include/linux/blkdev.h | 36 ++++++++++++++++++++++++++++++++++++
mm/bounce.c | 4 ++--
25 files changed, 147 insertions(+), 97 deletions(-)
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 0ab81a0..8714bb9 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -388,10 +388,10 @@ int blkdev_issue_discard(struct block_device *bdev,
bio->bi_sector = sector;
- if (nr_sects > q->max_hw_sectors) {
- bio->bi_size = q->max_hw_sectors << 9;
- nr_sects -= q->max_hw_sectors;
- sector += q->max_hw_sectors;
+ if (nr_sects > queue_max_hw_sectors(q)) {
+ bio->bi_size = queue_max_hw_sectors(q) << 9;
+ nr_sects -= queue_max_hw_sectors(q);
+ sector += queue_max_hw_sectors(q);
} else {
bio->bi_size = nr_sects << 9;
nr_sects = 0;
diff --git a/block/blk-core.c b/block/blk-core.c
index a2d97de..c924303 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1383,11 +1383,11 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;
}
- if (unlikely(nr_sectors > q->max_hw_sectors)) {
+ if (unlikely(nr_sectors > queue_max_hw_sectors(q))) {
printk(KERN_ERR "bio too big device %s (%u > %u)\n",
- bdevname(bio->bi_bdev, b),
- bio_sectors(bio),
- q->max_hw_sectors);
+ bdevname(bio->bi_bdev, b),
+ bio_sectors(bio),
+ queue_max_hw_sectors(q));
goto end_io;
}
@@ -1554,8 +1554,8 @@ EXPORT_SYMBOL(submit_bio);
*/
int blk_rq_check_limits(struct request_queue *q, struct request *rq)
{
- if (blk_rq_sectors(rq) > q->max_sectors ||
- blk_rq_bytes(rq) > q->max_hw_sectors << 9) {
+ if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
+ blk_rq_bytes(rq) > queue_max_hw_sectors(q) << 9) {
printk(KERN_ERR "%s: over max size limit.\n", __func__);
return -EIO;
}
@@ -1567,8 +1567,8 @@ int blk_rq_check_limits(struct request_queue *q, struct request *rq)
* limitation.
*/
blk_recalc_rq_segments(rq);
- if (rq->nr_phys_segments > q->max_phys_segments ||
- rq->nr_phys_segments > q->max_hw_segments) {
+ if (rq->nr_phys_segments > queue_max_phys_segments(q) ||
+ rq->nr_phys_segments > queue_max_hw_segments(q)) {
printk(KERN_ERR "%s: over max segments limit.\n", __func__);
return -EIO;
}
diff --git a/block/blk-map.c b/block/blk-map.c
index 56082be..da64add 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -116,7 +116,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
struct bio *bio = NULL;
int ret;
- if (len > (q->max_hw_sectors << 9))
+ if (len > (queue_max_hw_sectors(q) << 9))
return -EINVAL;
if (!len)
return -EINVAL;
@@ -291,7 +291,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
int do_copy = 0;
struct bio *bio;
- if (len > (q->max_hw_sectors << 9))
+ if (len > (queue_max_hw_sectors(q) << 9))
return -EINVAL;
if (!len || !kbuf)
return -EINVAL;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 4974dd5..39ce644 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -32,11 +32,12 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
* never considered part of another segment, since that
* might change with the bounce page.
*/
- high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
+ high = page_to_pfn(bv->bv_page) > queue_bounce_pfn(q);
if (high || highprv)
goto new_segment;
if (cluster) {
- if (seg_size + bv->bv_len > q->max_segment_size)
+ if (seg_size + bv->bv_len
+ > queue_max_segment_size(q))
goto new_segment;
if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
goto new_segment;
@@ -91,7 +92,7 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
return 0;
if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
- q->max_segment_size)
+ queue_max_segment_size(q))
return 0;
if (!bio_has_data(bio))
@@ -134,7 +135,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
int nbytes = bvec->bv_len;
if (bvprv && cluster) {
- if (sg->length + nbytes > q->max_segment_size)
+ if (sg->length + nbytes > queue_max_segment_size(q))
goto new_segment;
if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
@@ -205,8 +206,8 @@ static inline int ll_new_hw_segment(struct request_queue *q,
{
int nr_phys_segs = bio_phys_segments(q, bio);
- if (req->nr_phys_segments + nr_phys_segs > q->max_hw_segments
- || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
+ if (req->nr_phys_segments + nr_phys_segs > queue_max_hw_segments(q) ||
+ req->nr_phys_segments + nr_phys_segs > queue_max_phys_segments(q)) {
req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -227,9 +228,9 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
unsigned short max_sectors;
if (unlikely(blk_pc_request(req)))
- max_sectors = q->max_hw_sectors;
+ max_sectors = queue_max_hw_sectors(q);
else
- max_sectors = q->max_sectors;
+ max_sectors = queue_max_sectors(q);
if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
req->cmd_flags |= REQ_NOMERGE;
@@ -251,9 +252,9 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
unsigned short max_sectors;
if (unlikely(blk_pc_request(req)))
- max_sectors = q->max_hw_sectors;
+ max_sectors = queue_max_hw_sectors(q);
else
- max_sectors = q->max_sectors;
+ max_sectors = queue_max_sectors(q);
if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
@@ -287,7 +288,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
/*
* Will it become too large?
*/
- if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > q->max_sectors)
+ if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > queue_max_sectors(q))
return 0;
total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
@@ -299,10 +300,10 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
total_phys_segments--;
}
- if (total_phys_segments > q->max_phys_segments)
+ if (total_phys_segments > queue_max_phys_segments(q))
return 0;
- if (total_phys_segments > q->max_hw_segments)
+ if (total_phys_segments > queue_max_hw_segments(q))
return 0;
/* Merge is OK... */
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 15c3164..0b32f98 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -219,6 +219,15 @@ void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors)
}
EXPORT_SYMBOL(blk_queue_max_sectors);
+void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
+{
+ if (BLK_DEF_MAX_SECTORS > max_sectors)
+ q->max_hw_sectors = BLK_DEF_MAX_SECTORS;
+ else
+ q->max_hw_sectors = max_sectors;
+}
+EXPORT_SYMBOL(blk_queue_max_hw_sectors);
+
/**
* blk_queue_max_phys_segments - set max phys segments for a request for this queue
* @q: the request queue for the device
@@ -395,11 +404,11 @@ int blk_queue_dma_drain(struct request_queue *q,
dma_drain_needed_fn *dma_drain_needed,
void *buf, unsigned int size)
{
- if (q->max_hw_segments < 2 || q->max_phys_segments < 2)
+ if (queue_max_hw_segments(q) < 2 || queue_max_phys_segments(q) < 2)
return -EINVAL;
/* make room for appending the drain */
- --q->max_hw_segments;
- --q->max_phys_segments;
+ blk_queue_max_hw_segments(q, queue_max_hw_segments(q) - 1);
+ blk_queue_max_phys_segments(q, queue_max_phys_segments(q) - 1);
q->dma_drain_needed = dma_drain_needed;
q->dma_drain_buffer = buf;
q->dma_drain_size = size;
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 13d38b7..142a4ac 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -95,7 +95,7 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count)
static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
{
- int max_sectors_kb = q->max_sectors >> 1;
+ int max_sectors_kb = queue_max_sectors(q) >> 1;
return queue_var_show(max_sectors_kb, (page));
}
@@ -109,7 +109,7 @@ static ssize_t
queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
{
unsigned long max_sectors_kb,
- max_hw_sectors_kb = q->max_hw_sectors >> 1,
+ max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1,
page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
@@ -117,7 +117,7 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
return -EINVAL;
spin_lock_irq(q->queue_lock);
- q->max_sectors = max_sectors_kb << 1;
+ blk_queue_max_sectors(q, max_sectors_kb << 1);
spin_unlock_irq(q->queue_lock);
return ret;
@@ -125,7 +125,7 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page)
{
- int max_hw_sectors_kb = q->max_hw_sectors >> 1;
+ int max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1;
return queue_var_show(max_hw_sectors_kb, (page));
}
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 9eaa194..df18a15 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -766,7 +766,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return compat_put_int(arg, bdev_logical_block_size(bdev));
case BLKSECTGET:
return compat_put_ushort(arg,
- bdev_get_queue(bdev)->max_sectors);
+ queue_max_sectors(bdev_get_queue(bdev)));
case BLKRASET: /* compatible, but no compat_ptr (!) */
case BLKFRASET:
if (!capable(CAP_SYS_ADMIN))
diff --git a/block/ioctl.c b/block/ioctl.c
index 7aa97f6..500e4c7 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -152,10 +152,10 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
bio->bi_private = &wait;
bio->bi_sector = start;
- if (len > q->max_hw_sectors) {
- bio->bi_size = q->max_hw_sectors << 9;
- len -= q->max_hw_sectors;
- start += q->max_hw_sectors;
+ if (len > queue_max_hw_sectors(q)) {
+ bio->bi_size = queue_max_hw_sectors(q) << 9;
+ len -= queue_max_hw_sectors(q);
+ start += queue_max_hw_sectors(q);
} else {
bio->bi_size = len << 9;
len = 0;
@@ -313,7 +313,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
case BLKSSZGET: /* get block device hardware sector size */
return put_int(arg, bdev_logical_block_size(bdev));
case BLKSECTGET:
- return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
+ return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
case BLKRASET:
case BLKFRASET:
if(!capable(CAP_SYS_ADMIN))
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index a9670dd..5f8e798 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -75,7 +75,7 @@ static int sg_set_timeout(struct request_queue *q, int __user *p)
static int sg_get_reserved_size(struct request_queue *q, int __user *p)
{
- unsigned val = min(q->sg_reserved_size, q->max_sectors << 9);
+ unsigned val = min(q->sg_reserved_size, queue_max_sectors(q) << 9);
return put_user(val, p);
}
@@ -89,8 +89,8 @@ static int sg_set_reserved_size(struct request_queue *q, int __user *p)
if (size < 0)
return -EINVAL;
- if (size > (q->max_sectors << 9))
- size = q->max_sectors << 9;
+ if (size > (queue_max_sectors(q) << 9))
+ size = queue_max_sectors(q) << 9;
q->sg_reserved_size = size;
return 0;
@@ -264,7 +264,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
if (hdr->cmd_len > BLK_MAX_CDB)
return -EINVAL;
- if (hdr->dxfer_len > (q->max_hw_sectors << 9))
+ if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9))
return -EIO;
if (hdr->dxfer_len)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 293f585..d57f117 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -991,13 +991,15 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
*/
static int pkt_set_segment_merging(struct pktcdvd_device *pd, struct request_queue *q)
{
- if ((pd->settings.size << 9) / CD_FRAMESIZE <= q->max_phys_segments) {
+ if ((pd->settings.size << 9) / CD_FRAMESIZE
+ <= queue_max_phys_segments(q)) {
/*
* The cdrom device can handle one segment/frame
*/
clear_bit(PACKET_MERGE_SEGS, &pd->flags);
return 0;
- } else if ((pd->settings.size << 9) / PAGE_SIZE <= q->max_phys_segments) {
+ } else if ((pd->settings.size << 9) / PAGE_SIZE
+ <= queue_max_phys_segments(q)) {
/*
* We can handle this case at the expense of some extra memory
* copies during write operations
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index cceace6..71d1b9b 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2101,8 +2101,8 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
nr = nframes;
if (cdi->cdda_method == CDDA_BPC_SINGLE)
nr = 1;
- if (nr * CD_FRAMESIZE_RAW > (q->max_sectors << 9))
- nr = (q->max_sectors << 9) / CD_FRAMESIZE_RAW;
+ if (nr * CD_FRAMESIZE_RAW > (queue_max_sectors(q) << 9))
+ nr = (queue_max_sectors(q) << 9) / CD_FRAMESIZE_RAW;
len = nr * CD_FRAMESIZE_RAW;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 65e2d97..e9a73bb 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -510,7 +510,7 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
* combine_restrictions_low()
*/
rs->max_sectors =
- min_not_zero(rs->max_sectors, q->max_sectors);
+ min_not_zero(rs->max_sectors, queue_max_sectors(q));
/*
* Check if merge fn is supported.
@@ -525,25 +525,25 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
rs->max_phys_segments =
min_not_zero(rs->max_phys_segments,
- q->max_phys_segments);
+ queue_max_phys_segments(q));
rs->max_hw_segments =
- min_not_zero(rs->max_hw_segments, q->max_hw_segments);
+ min_not_zero(rs->max_hw_segments, queue_max_hw_segments(q));
rs->logical_block_size = max(rs->logical_block_size,
queue_logical_block_size(q));
rs->max_segment_size =
- min_not_zero(rs->max_segment_size, q->max_segment_size);
+ min_not_zero(rs->max_segment_size, queue_max_segment_size(q));
rs->max_hw_sectors =
- min_not_zero(rs->max_hw_sectors, q->max_hw_sectors);
+ min_not_zero(rs->max_hw_sectors, queue_max_hw_sectors(q));
rs->seg_boundary_mask =
min_not_zero(rs->seg_boundary_mask,
- q->seg_boundary_mask);
+ queue_segment_boundary(q));
- rs->bounce_pfn = min_not_zero(rs->bounce_pfn, q->bounce_pfn);
+ rs->bounce_pfn = min_not_zero(rs->bounce_pfn, queue_bounce_pfn(q));
rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
}
@@ -914,13 +914,13 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
* restrictions.
*/
blk_queue_max_sectors(q, t->limits.max_sectors);
- q->max_phys_segments = t->limits.max_phys_segments;
- q->max_hw_segments = t->limits.max_hw_segments;
- q->logical_block_size = t->limits.logical_block_size;
- q->max_segment_size = t->limits.max_segment_size;
- q->max_hw_sectors = t->limits.max_hw_sectors;
- q->seg_boundary_mask = t->limits.seg_boundary_mask;
- q->bounce_pfn = t->limits.bounce_pfn;
+ blk_queue_max_phys_segments(q, t->limits.max_phys_segments);
+ blk_queue_max_hw_segments(q, t->limits.max_hw_segments);
+ blk_queue_logical_block_size(q, t->limits.logical_block_size);
+ blk_queue_max_segment_size(q, t->limits.max_segment_size);
+ blk_queue_max_hw_sectors(q, t->limits.max_hw_sectors);
+ blk_queue_segment_boundary(q, t->limits.seg_boundary_mask);
+ blk_queue_bounce_limit(q, t->limits.bounce_pfn);
if (t->limits.no_cluster)
queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 7a36e38..64f1f3e 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -146,7 +146,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
disk->num_sectors = rdev->sectors;
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 41ced0c..4ee31aa 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -303,7 +303,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
* merge_bvec_fn will be involved in multipath.)
*/
if (q->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+ queue_max_sectors(q) > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
conf->working_disks++;
@@ -467,7 +467,7 @@ static int multipath_run (mddev_t *mddev)
* violating it, not that we ever expect a device with
* a merge_bvec_fn to be involved in multipath */
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
if (!test_bit(Faulty, &rdev->flags))
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c08d755..925507e 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -144,7 +144,7 @@ static int create_strip_zones (mddev_t *mddev)
*/
if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
if (!smallest || (rdev1->sectors < smallest->sectors))
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 36df910..e23758b 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1130,7 +1130,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
p->head_position = 0;
@@ -1996,7 +1996,7 @@ static int run(mddev_t *mddev)
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
disk->head_position = 0;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 81a54f1..1a41aea 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1158,8 +1158,8 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
- mddev->queue->max_sectors = (PAGE_SIZE>>9);
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
+ blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
p->head_position = 0;
rdev->raid_disk = mirror;
@@ -2145,8 +2145,8 @@ static int run(mddev_t *mddev)
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
- mddev->queue->max_sectors > (PAGE_SIZE>>9))
- mddev->queue->max_sectors = (PAGE_SIZE>>9);
+ queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
+ blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
disk->head_position = 0;
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 4616bc3..7970dc8 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3463,10 +3463,10 @@ static int bio_fits_rdev(struct bio *bi)
{
struct request_queue *q = bdev_get_queue(bi->bi_bdev);
- if ((bi->bi_size>>9) > q->max_sectors)
+ if ((bi->bi_size>>9) > queue_max_sectors(q))
return 0;
blk_recount_segments(q, bi);
- if (bi->bi_phys_segments > q->max_phys_segments)
+ if (bi->bi_phys_segments > queue_max_phys_segments(q))
return 0;
if (q->merge_bvec_fn)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index dec4c70..350f430 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -289,8 +289,8 @@ sg_open(struct inode *inode, struct file *filp)
if (list_empty(&sdp->sfds)) { /* no existing opens on this device */
sdp->sgdebug = 0;
q = sdp->device->request_queue;
- sdp->sg_tablesize = min(q->max_hw_segments,
- q->max_phys_segments);
+ sdp->sg_tablesize = min(queue_max_hw_segments(q),
+ queue_max_phys_segments(q));
}
if ((sfp = sg_add_sfp(sdp, dev)))
filp->private_data = sfp;
@@ -909,7 +909,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (val < 0)
return -EINVAL;
val = min_t(int, val,
- sdp->device->request_queue->max_sectors * 512);
+ queue_max_sectors(sdp->device->request_queue) * 512);
if (val != sfp->reserve.bufflen) {
if (sg_res_in_use(sfp) || sfp->mmap_called)
return -EBUSY;
@@ -919,7 +919,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
return 0;
case SG_GET_RESERVED_SIZE:
val = min_t(int, sfp->reserve.bufflen,
- sdp->device->request_queue->max_sectors * 512);
+ queue_max_sectors(sdp->device->request_queue) * 512);
return put_user(val, ip);
case SG_SET_COMMAND_Q:
result = get_user(val, ip);
@@ -1059,7 +1059,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
return -ENODEV;
return scsi_ioctl(sdp->device, cmd_in, p);
case BLKSECTGET:
- return put_user(sdp->device->request_queue->max_sectors * 512,
+ return put_user(queue_max_sectors(sdp->device->request_queue) * 512,
ip);
case BLKTRACESETUP:
return blk_trace_setup(sdp->device->request_queue,
@@ -1377,7 +1377,8 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
sdp->device = scsidp;
INIT_LIST_HEAD(&sdp->sfds);
init_waitqueue_head(&sdp->o_excl_wait);
- sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
+ sdp->sg_tablesize = min(queue_max_hw_segments(q),
+ queue_max_phys_segments(q));
sdp->index = k;
kref_init(&sdp->d_ref);
@@ -2052,7 +2053,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
sg_big_buff = def_reserved_size;
bufflen = min_t(int, sg_big_buff,
- sdp->device->request_queue->max_sectors * 512);
+ queue_max_sectors(sdp->device->request_queue) * 512);
sg_build_reserve(sfp, bufflen);
SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n",
sfp->reserve.bufflen, sfp->reserve.k_use_sg));
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 8681b70..89bd438 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3983,8 +3983,8 @@ static int st_probe(struct device *dev)
return -ENODEV;
}
- i = min(SDp->request_queue->max_hw_segments,
- SDp->request_queue->max_phys_segments);
+ i = min(queue_max_hw_segments(SDp->request_queue),
+ queue_max_phys_segments(SDp->request_queue));
if (st_max_sg_segs < i)
i = st_max_sg_segs;
buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 4ca3b58..cfa26d5 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -132,7 +132,7 @@ static int slave_configure(struct scsi_device *sdev)
if (us->fflags & US_FL_MAX_SECTORS_MIN)
max_sectors = PAGE_CACHE_SIZE >> 9;
- if (sdev->request_queue->max_sectors > max_sectors)
+ if (queue_max_sectors(sdev->request_queue) > max_sectors)
blk_queue_max_sectors(sdev->request_queue,
max_sectors);
} else if (sdev->type == TYPE_TAPE) {
@@ -483,7 +483,7 @@ static ssize_t show_max_sectors(struct device *dev, struct device_attribute *att
{
struct scsi_device *sdev = to_scsi_device(dev);
- return sprintf(buf, "%u\n", sdev->request_queue->max_sectors);
+ return sprintf(buf, "%u\n", queue_max_sectors(sdev->request_queue));
}
/* Input routine for the sysfs max_sectors file */
diff --git a/fs/bio.c b/fs/bio.c
index 28f9f17..05a356b 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -499,11 +499,11 @@ int bio_get_nr_vecs(struct block_device *bdev)
struct request_queue *q = bdev_get_queue(bdev);
int nr_pages;
- nr_pages = ((q->max_sectors << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (nr_pages > q->max_phys_segments)
- nr_pages = q->max_phys_segments;
- if (nr_pages > q->max_hw_segments)
- nr_pages = q->max_hw_segments;
+ nr_pages = ((queue_max_sectors(q) << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (nr_pages > queue_max_phys_segments(q))
+ nr_pages = queue_max_phys_segments(q);
+ if (nr_pages > queue_max_hw_segments(q))
+ nr_pages = queue_max_hw_segments(q);
return nr_pages;
}
@@ -562,8 +562,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
* make this too complex.
*/
- while (bio->bi_phys_segments >= q->max_phys_segments
- || bio->bi_phys_segments >= q->max_hw_segments) {
+ while (bio->bi_phys_segments >= queue_max_phys_segments(q)
+ || bio->bi_phys_segments >= queue_max_hw_segments(q)) {
if (retried_segments)
return 0;
@@ -634,7 +634,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page,
unsigned int len, unsigned int offset)
{
- return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors);
+ return __bio_add_page(q, bio, page, len, offset,
+ queue_max_hw_sectors(q));
}
/**
@@ -654,7 +655,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
unsigned int offset)
{
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
- return __bio_add_page(q, bio, page, len, offset, q->max_sectors);
+ return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q));
}
struct bio_map_data {
diff --git a/include/linux/bio.h b/include/linux/bio.h
index d30ec6f..12737be 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -279,7 +279,7 @@ static inline int bio_has_allocated_vec(struct bio *bio)
#define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \
(((addr1) | (mask)) == (((addr2) - 1) | (mask)))
#define BIOVEC_SEG_BOUNDARY(q, b1, b2) \
- __BIO_SEG_BOUNDARY(bvec_to_phys((b1)), bvec_to_phys((b2)) + (b2)->bv_len, (q)->seg_boundary_mask)
+ __BIO_SEG_BOUNDARY(bvec_to_phys((b1)), bvec_to_phys((b2)) + (b2)->bv_len, queue_segment_boundary((q)))
#define BIO_SEG_BOUNDARY(q, b1, b2) \
BIOVEC_SEG_BOUNDARY((q), __BVEC_END((b1)), __BVEC_START((b2)))
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 85c7f7d..e7950df 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -896,6 +896,7 @@ extern void blk_cleanup_queue(struct request_queue *);
extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
extern void blk_queue_bounce_limit(struct request_queue *, u64);
extern void blk_queue_max_sectors(struct request_queue *, unsigned int);
+extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
@@ -986,6 +987,41 @@ extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
#define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
+static inline unsigned long queue_bounce_pfn(struct request_queue *q)
+{
+ return q->bounce_pfn;
+}
+
+static inline unsigned long queue_segment_boundary(struct request_queue *q)
+{
+ return q->seg_boundary_mask;
+}
+
+static inline unsigned int queue_max_sectors(struct request_queue *q)
+{
+ return q->max_sectors;
+}
+
+static inline unsigned int queue_max_hw_sectors(struct request_queue *q)
+{
+ return q->max_hw_sectors;
+}
+
+static inline unsigned short queue_max_hw_segments(struct request_queue *q)
+{
+ return q->max_hw_segments;
+}
+
+static inline unsigned short queue_max_phys_segments(struct request_queue *q)
+{
+ return q->max_phys_segments;
+}
+
+static inline unsigned int queue_max_segment_size(struct request_queue *q)
+{
+ return q->max_segment_size;
+}
+
static inline unsigned short queue_logical_block_size(struct request_queue *q)
{
int retval = 512;
diff --git a/mm/bounce.c b/mm/bounce.c
index e590272..8dcd431 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -192,7 +192,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
/*
* is destination page below bounce pfn?
*/
- if (page_to_pfn(page) <= q->bounce_pfn)
+ if (page_to_pfn(page) <= queue_bounce_pfn(q))
continue;
/*
@@ -284,7 +284,7 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
* don't waste time iterating over bio segments
*/
if (!(q->bounce_gfp & GFP_DMA)) {
- if (q->bounce_pfn >= blk_max_pfn)
+ if (queue_bounce_pfn(q) >= blk_max_pfn)
return;
pool = page_pool;
} else {
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 03/13] block: Move queue limits to an embedded struct
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
2009-05-15 4:40 ` [PATCH 01/13] block: Do away with the notion of hardsect_size Martin K. Petersen
2009-05-15 4:40 ` [PATCH 02/13] block: Use accessor functions for queue limits Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-18 18:50 ` Mike Snitzer
2009-05-15 4:40 ` [PATCH 04/13] block: Expose stacked device queues in sysfs Martin K. Petersen
` (9 subsequent siblings)
12 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
To accommodate stacking drivers that do not have an associated request
queue we're moving the limits to a separate, embedded structure.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
block/blk-settings.c | 55 +++++++++++++++++++++++++++++------------------
include/linux/blkdev.h | 44 ++++++++++++++++++++++---------------
2 files changed, 60 insertions(+), 39 deletions(-)
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 0b32f98..b0f547c 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -179,16 +179,16 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
*/
if (b_pfn < (min_t(u64, 0xffffffffUL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
dma = 1;
- q->bounce_pfn = max_low_pfn;
+ q->limits.bounce_pfn = max_low_pfn;
#else
if (b_pfn < blk_max_low_pfn)
dma = 1;
- q->bounce_pfn = b_pfn;
+ q->limits.bounce_pfn = b_pfn;
#endif
if (dma) {
init_emergency_isa_pool();
q->bounce_gfp = GFP_NOIO | GFP_DMA;
- q->bounce_pfn = b_pfn;
+ q->limits.bounce_pfn = b_pfn;
}
}
EXPORT_SYMBOL(blk_queue_bounce_limit);
@@ -211,10 +211,10 @@ void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors)
}
if (BLK_DEF_MAX_SECTORS > max_sectors)
- q->max_hw_sectors = q->max_sectors = max_sectors;
+ q->limits.max_hw_sectors = q->limits.max_sectors = max_sectors;
else {
- q->max_sectors = BLK_DEF_MAX_SECTORS;
- q->max_hw_sectors = max_sectors;
+ q->limits.max_sectors = BLK_DEF_MAX_SECTORS;
+ q->limits.max_hw_sectors = max_sectors;
}
}
EXPORT_SYMBOL(blk_queue_max_sectors);
@@ -222,9 +222,9 @@ EXPORT_SYMBOL(blk_queue_max_sectors);
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
{
if (BLK_DEF_MAX_SECTORS > max_sectors)
- q->max_hw_sectors = BLK_DEF_MAX_SECTORS;
+ q->limits.max_hw_sectors = BLK_DEF_MAX_SECTORS;
else
- q->max_hw_sectors = max_sectors;
+ q->limits.max_hw_sectors = max_sectors;
}
EXPORT_SYMBOL(blk_queue_max_hw_sectors);
@@ -247,7 +247,7 @@ void blk_queue_max_phys_segments(struct request_queue *q,
__func__, max_segments);
}
- q->max_phys_segments = max_segments;
+ q->limits.max_phys_segments = max_segments;
}
EXPORT_SYMBOL(blk_queue_max_phys_segments);
@@ -271,7 +271,7 @@ void blk_queue_max_hw_segments(struct request_queue *q,
__func__, max_segments);
}
- q->max_hw_segments = max_segments;
+ q->limits.max_hw_segments = max_segments;
}
EXPORT_SYMBOL(blk_queue_max_hw_segments);
@@ -292,7 +292,7 @@ void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size)
__func__, max_size);
}
- q->max_segment_size = max_size;
+ q->limits.max_segment_size = max_size;
}
EXPORT_SYMBOL(blk_queue_max_segment_size);
@@ -308,7 +308,7 @@ EXPORT_SYMBOL(blk_queue_max_segment_size);
**/
void blk_queue_logical_block_size(struct request_queue *q, unsigned short size)
{
- q->logical_block_size = size;
+ q->limits.logical_block_size = size;
}
EXPORT_SYMBOL(blk_queue_logical_block_size);
@@ -325,14 +325,27 @@ EXPORT_SYMBOL(blk_queue_logical_block_size);
void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
{
/* zero is "infinity" */
- t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
- t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
- t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask, b->seg_boundary_mask);
-
- t->max_phys_segments = min_not_zero(t->max_phys_segments, b->max_phys_segments);
- t->max_hw_segments = min_not_zero(t->max_hw_segments, b->max_hw_segments);
- t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size);
- t->logical_block_size = max(t->logical_block_size, b->logical_block_size);
+ t->limits.max_sectors = min_not_zero(queue_max_sectors(t),
+ queue_max_sectors(b));
+
+ t->limits.max_hw_sectors = min_not_zero(queue_max_hw_sectors(t),
+ queue_max_hw_sectors(b));
+
+ t->limits.seg_boundary_mask = min_not_zero(queue_segment_boundary(t),
+ queue_segment_boundary(b));
+
+ t->limits.max_phys_segments = min_not_zero(queue_max_phys_segments(t),
+ queue_max_phys_segments(b));
+
+ t->limits.max_hw_segments = min_not_zero(queue_max_hw_segments(t),
+ queue_max_hw_segments(b));
+
+ t->limits.max_segment_size = min_not_zero(queue_max_segment_size(t),
+ queue_max_segment_size(b));
+
+ t->limits.logical_block_size = max(queue_logical_block_size(t),
+ queue_logical_block_size(b));
+
if (!t->queue_lock)
WARN_ON_ONCE(1);
else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
@@ -430,7 +443,7 @@ void blk_queue_segment_boundary(struct request_queue *q, unsigned long mask)
__func__, mask);
}
- q->seg_boundary_mask = mask;
+ q->limits.seg_boundary_mask = mask;
}
EXPORT_SYMBOL(blk_queue_segment_boundary);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e7950df..2655673 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -307,6 +307,21 @@ struct blk_cmd_filter {
struct kobject kobj;
};
+struct queue_limits {
+ unsigned long bounce_pfn;
+ unsigned long seg_boundary_mask;
+
+ unsigned int max_hw_sectors;
+ unsigned int max_sectors;
+ unsigned int max_segment_size;
+
+ unsigned short logical_block_size;
+ unsigned short max_hw_segments;
+ unsigned short max_phys_segments;
+
+ unsigned char no_cluster;
+};
+
struct request_queue
{
/*
@@ -358,7 +373,6 @@ struct request_queue
/*
* queue needs bounce pages for pages above this limit
*/
- unsigned long bounce_pfn;
gfp_t bounce_gfp;
/*
@@ -387,14 +401,6 @@ struct request_queue
unsigned int nr_congestion_off;
unsigned int nr_batching;
- unsigned int max_sectors;
- unsigned int max_hw_sectors;
- unsigned short max_phys_segments;
- unsigned short max_hw_segments;
- unsigned short logical_block_size;
- unsigned int max_segment_size;
-
- unsigned long seg_boundary_mask;
void *dma_drain_buffer;
unsigned int dma_drain_size;
unsigned int dma_pad_mask;
@@ -410,6 +416,8 @@ struct request_queue
struct timer_list timeout;
struct list_head timeout_list;
+ struct queue_limits limits;
+
/*
* sg stuff
*/
@@ -989,45 +997,45 @@ extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
static inline unsigned long queue_bounce_pfn(struct request_queue *q)
{
- return q->bounce_pfn;
+ return q->limits.bounce_pfn;
}
static inline unsigned long queue_segment_boundary(struct request_queue *q)
{
- return q->seg_boundary_mask;
+ return q->limits.seg_boundary_mask;
}
static inline unsigned int queue_max_sectors(struct request_queue *q)
{
- return q->max_sectors;
+ return q->limits.max_sectors;
}
static inline unsigned int queue_max_hw_sectors(struct request_queue *q)
{
- return q->max_hw_sectors;
+ return q->limits.max_hw_sectors;
}
static inline unsigned short queue_max_hw_segments(struct request_queue *q)
{
- return q->max_hw_segments;
+ return q->limits.max_hw_segments;
}
static inline unsigned short queue_max_phys_segments(struct request_queue *q)
{
- return q->max_phys_segments;
+ return q->limits.max_phys_segments;
}
static inline unsigned int queue_max_segment_size(struct request_queue *q)
{
- return q->max_segment_size;
+ return q->limits.max_segment_size;
}
static inline unsigned short queue_logical_block_size(struct request_queue *q)
{
int retval = 512;
- if (q && q->logical_block_size)
- retval = q->logical_block_size;
+ if (q && q->limits.logical_block_size)
+ retval = q->limits.logical_block_size;
return retval;
}
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 04/13] block: Expose stacked device queues in sysfs
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (2 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 03/13] block: Move queue limits to an embedded struct Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 05/13] block: Export I/O topology for block devices and partitions Martin K. Petersen
` (8 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Currently stacking devices do not have a queue directory in sysfs.
However, many of the I/O characteristics like sector size, maximum
request size, etc. are queue properties.
This patch enables the queue directory for MD/DM devices. The elevator
code has been modified to deal with queues that do not have an I/O
scheduler.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
block/blk-sysfs.c | 6 +++---
block/elevator.c | 13 ++++++++++++-
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 142a4ac..3ccdadb 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -395,9 +395,6 @@ int blk_register_queue(struct gendisk *disk)
if (WARN_ON(!q))
return -ENXIO;
- if (!q->request_fn)
- return 0;
-
ret = kobject_add(&q->kobj, kobject_get(&disk_to_dev(disk)->kobj),
"%s", "queue");
if (ret < 0)
@@ -405,6 +402,9 @@ int blk_register_queue(struct gendisk *disk)
kobject_uevent(&q->kobj, KOBJ_ADD);
+ if (!q->request_fn)
+ return 0;
+
ret = elv_register_queue(q);
if (ret) {
kobject_uevent(&q->kobj, KOBJ_REMOVE);
diff --git a/block/elevator.c b/block/elevator.c
index 9189200..143fb6a 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -575,6 +575,9 @@ void elv_drain_elevator(struct request_queue *q)
*/
void elv_quiesce_start(struct request_queue *q)
{
+ if (!q->elevator)
+ return;
+
queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
/*
@@ -1050,6 +1053,9 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
char elevator_name[ELV_NAME_MAX];
struct elevator_type *e;
+ if (!q->elevator)
+ return count;
+
strlcpy(elevator_name, name, sizeof(elevator_name));
strstrip(elevator_name);
@@ -1073,10 +1079,15 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
ssize_t elv_iosched_show(struct request_queue *q, char *name)
{
struct elevator_queue *e = q->elevator;
- struct elevator_type *elv = e->elevator_type;
+ struct elevator_type *elv;
struct elevator_type *__e;
int len = 0;
+ if (!q->elevator)
+ return sprintf(name, "none\n");
+
+ elv = e->elevator_type;
+
spin_lock(&elv_list_lock);
list_for_each_entry(__e, &elv_list, list) {
if (!strcmp(elv->elevator_name, __e->elevator_name))
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (3 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 04/13] block: Expose stacked device queues in sysfs Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-18 17:57 ` Jens Axboe
2009-05-15 4:40 ` [PATCH 06/13] MD: Use new topology calls to indicate alignment and I/O sizes Martin K. Petersen
` (7 subsequent siblings)
12 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
To support devices with physical block sizes bigger than 512 bytes we
need to ensure proper alignment. This patch adds support for exposing
I/O topology characteristics as devices are stacked.
logical_block_size is the smallest unit the device can address.
physical_block_size indicates the smallest I/O the device can write
without incurring a read-modify-write penalty.
The io_min parameter is the smallest preferred I/O size reported by
the device. In many cases this is the same as the physical block
size. However, the io_min parameter can be scaled up when stacking
(RAID5 chunk size > physical block size).
The io_opt characteristic indicates the optimal I/O size reported by
the device. This is usually the stripe width for arrays.
The io_alignment parameter indicates the number of bytes the start of
the device/partition is offset from the device's natural alignment.
Partition tools and MD/DM utilities can use this to pad their offsets
so filesystem start on proper boundaries.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
Documentation/ABI/testing/sysfs-block | 59 +++++++++++
block/blk-settings.c | 184 +++++++++++++++++++++++++++++++++
block/blk-sysfs.c | 33 ++++++
block/genhd.c | 10 ++
fs/partitions/check.c | 10 ++
include/linux/blkdev.h | 47 +++++++++
include/linux/genhd.h | 1 +
7 files changed, 344 insertions(+), 0 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
index 44f52a4..93075cf 100644
--- a/Documentation/ABI/testing/sysfs-block
+++ b/Documentation/ABI/testing/sysfs-block
@@ -60,3 +60,62 @@ Description:
Indicates whether the block layer should automatically
generate checksums for write requests bound for
devices that support receiving integrity metadata.
+
+What: /sys/block/<disk>/alignment
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report a physical block size that is
+ bigger than the logical block size (for instance a drive
+ with 4KB physical sectors exposing 512-byte logical
+ blocks to the operating system). This parameter
+ indicates how many bytes the beginning of the device is
+ offset from the disk's natural alignment.
+
+What: /sys/block/<disk>/<partition>/alignment
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report a physical block size that is
+ bigger than the logical block size (for instance a drive
+ with 4KB physical sectors exposing 512-byte logical
+ blocks to the operating system). This parameter
+ indicates how many bytes the beginning of the partition
+ is offset from the disk's natural alignment.
+
+What: /sys/block/<disk>/queue/logical_block_size
+Date: May 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ This is the smallest unit the storage device can
+ address. It is typically 512 bytes.
+
+What: /sys/block/<disk>/queue/physical_block_size
+Date: May 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ This is the smallest unit the storage device can write
+ without resorting to read-modify-write operation. It is
+ usually the same as the logical block size but may be
+ bigger. One example is SATA drives with 4KB sectors
+ that expose a 512-byte logical block size to the
+ operating system.
+
+What: /sys/block/<disk>/queue/minimum_io_size
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report a preferred minimum I/O size,
+ which is the smallest request the device can perform
+ without incurring a read-modify-write penalty. For disk
+ drives this is often the physical block size. For RAID
+ arrays it is often the stripe chunk size.
+
+What: /sys/block/<disk>/queue/optimal_io_size
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report an optimal I/O size, which is
+ the device's preferred unit of receiving I/O. This is
+ rarely reported for disk drives. For RAID devices it is
+ usually the stripe width or the internal block size.
diff --git a/block/blk-settings.c b/block/blk-settings.c
index b0f547c..aea6762 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -309,9 +309,93 @@ EXPORT_SYMBOL(blk_queue_max_segment_size);
void blk_queue_logical_block_size(struct request_queue *q, unsigned short size)
{
q->limits.logical_block_size = size;
+
+ if (q->limits.physical_block_size < size)
+ q->limits.physical_block_size = size;
+
+ if (q->limits.io_min < q->limits.physical_block_size)
+ q->limits.io_min = q->limits.physical_block_size;
}
EXPORT_SYMBOL(blk_queue_logical_block_size);
+/**
+ * blk_queue_physical_block_size - set physical block size for the queue
+ * @q: the request queue for the device
+ * @size: the physical block size, in bytes
+ *
+ * Description:
+ * This should be set to the lowest possible sector size that the
+ * hardware can operate on without reverting to read-modify-write
+ * operations.
+ */
+void blk_queue_physical_block_size(struct request_queue *q, unsigned short size)
+{
+ q->limits.physical_block_size = size;
+
+ if (q->limits.physical_block_size < q->limits.logical_block_size)
+ q->limits.physical_block_size = q->limits.logical_block_size;
+
+ if (q->limits.io_min < q->limits.physical_block_size)
+ q->limits.io_min = q->limits.physical_block_size;
+}
+EXPORT_SYMBOL(blk_queue_physical_block_size);
+
+/**
+ * blk_queue_io_alignment - set physical block alignment for the queue
+ * @q: the request queue for the device
+ * @alignment: alignment offset in bytes
+ *
+ * Description:
+ * Some devices are naturally misaligned to compensate for things like
+ * the legacy DOS partition table 63-sector offset. Low-level drivers
+ * should call this function for devices whose first sector is not
+ * naturally aligned.
+ */
+void blk_queue_io_alignment(struct request_queue *q, unsigned int alignment)
+{
+ q->limits.io_alignment = alignment & (q->limits.physical_block_size - 1);
+ q->limits.misaligned = 0;
+}
+EXPORT_SYMBOL(blk_queue_io_alignment);
+
+/**
+ * blk_queue_io_min - set minimum request size for the queue
+ * @q: the request queue for the device
+ * @io_min: smallest I/O size in bytes
+ *
+ * Description:
+ * Some devices have an internal block size bigger than the reported
+ * hardware sector size. This function can be used to signal the
+ * smallest I/O the device can perform without incurring a performance
+ * penalty.
+ */
+void blk_queue_io_min(struct request_queue *q, unsigned int min)
+{
+ q->limits.io_min = min;
+
+ if (q->limits.io_min < q->limits.logical_block_size)
+ q->limits.io_min = q->limits.logical_block_size;
+
+ if (q->limits.io_min < q->limits.physical_block_size)
+ q->limits.io_min = q->limits.physical_block_size;
+}
+EXPORT_SYMBOL(blk_queue_io_min);
+
+/**
+ * blk_queue_io_opt - set optimal request size for the queue
+ * @q: the request queue for the device
+ * @io_opt: optimal request size in bytes
+ *
+ * Description:
+ * Drivers can call this function to set the preferred I/O request
+ * size for devices that report such a value.
+ */
+void blk_queue_io_opt(struct request_queue *q, unsigned int opt)
+{
+ q->limits.io_opt = opt;
+}
+EXPORT_SYMBOL(blk_queue_io_opt);
+
/*
* Returns the minimum that is _not_ zero, unless both are zero.
*/
@@ -358,6 +442,106 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
EXPORT_SYMBOL(blk_queue_stack_limits);
/**
+ * blk_stack_limits - adjust queue_limits for stacked devices
+ * @t: the stacking driver limits (top)
+ * @bdev: the underlying queue limits (bottom)
+ * @offset: offset to beginning of data within component device
+ *
+ * Description:
+ * Merges two queue_limit structs. Returns 0 if alignment didn't
+ * change. Returns -1 if adding the bottom device caused
+ * misalignment.
+ */
+int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ sector_t offset)
+{
+ t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
+ t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
+
+ t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
+ b->seg_boundary_mask);
+
+ t->max_phys_segments = min_not_zero(t->max_phys_segments,
+ b->max_phys_segments);
+
+ t->max_hw_segments = min_not_zero(t->max_hw_segments,
+ b->max_hw_segments);
+
+ t->max_segment_size = min_not_zero(t->max_segment_size,
+ b->max_segment_size);
+
+ t->logical_block_size = max(t->logical_block_size,
+ b->logical_block_size);
+
+ t->physical_block_size = max(t->physical_block_size,
+ b->physical_block_size);
+
+ t->io_min = max(t->io_min, b->io_min);
+ t->no_cluster |= b->no_cluster;
+
+ /* Bottom device offset aligned? */
+ if (offset &&
+ (offset & (b->physical_block_size - 1)) != b->io_alignment) {
+ t->misaligned = 1;
+ return -1;
+ }
+
+ /* If top has no alignment, inherit from bottom */
+ if (!t->io_alignment)
+ t->io_alignment = b->io_alignment & (b->physical_block_size - 1);
+
+ /* Top alignment on logical block boundary? */
+ if (t->io_alignment & (t->logical_block_size - 1)) {
+ t->misaligned = 1;
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * disk_stack_limits - adjust queue limits for stacked drivers
+ * @t: MD/DM gendisk (top)
+ * @bdev: the underlying block device (bottom)
+ * @offset: offset to beginning of data within component device
+ *
+ * Description:
+ * Merges the limits for two queues. Returns 0 if alignment
+ * didn't change. Returns -1 if adding the bottom device caused
+ * misalignment.
+ */
+void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
+ sector_t offset)
+{
+ struct request_queue *t = disk->queue;
+ struct request_queue *b = bdev_get_queue(bdev);
+
+ offset += get_start_sect(bdev) << 9;
+
+ if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) {
+ char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
+
+ disk_name(disk, 0, top);
+ bdevname(bdev, bottom);
+
+ printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n",
+ top, bottom);
+ }
+
+ if (!t->queue_lock)
+ WARN_ON_ONCE(1);
+ else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(t->queue_lock, flags);
+ if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
+ queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
+ spin_unlock_irqrestore(t->queue_lock, flags);
+ }
+}
+EXPORT_SYMBOL(disk_stack_limits);
+
+/**
* blk_queue_dma_pad - set pad mask
* @q: the request queue for the device
* @mask: pad mask
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 3ccdadb..9337e17 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -105,6 +105,21 @@ static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page
return queue_var_show(queue_logical_block_size(q), page);
}
+static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_physical_block_size(q), page);
+}
+
+static ssize_t queue_io_min_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_io_min(q), page);
+}
+
+static ssize_t queue_io_opt_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_io_opt(q), page);
+}
+
static ssize_t
queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
{
@@ -257,6 +272,21 @@ static struct queue_sysfs_entry queue_logical_block_size_entry = {
.show = queue_logical_block_size_show,
};
+static struct queue_sysfs_entry queue_physical_block_size_entry = {
+ .attr = {.name = "physical_block_size", .mode = S_IRUGO },
+ .show = queue_physical_block_size_show,
+};
+
+static struct queue_sysfs_entry queue_io_min_entry = {
+ .attr = {.name = "minimum_io_size", .mode = S_IRUGO },
+ .show = queue_io_min_show,
+};
+
+static struct queue_sysfs_entry queue_io_opt_entry = {
+ .attr = {.name = "optimal_io_size", .mode = S_IRUGO },
+ .show = queue_io_opt_show,
+};
+
static struct queue_sysfs_entry queue_nonrot_entry = {
.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
.show = queue_nonrot_show,
@@ -289,6 +319,9 @@ static struct attribute *default_attrs[] = {
&queue_iosched_entry.attr,
&queue_hw_sector_size_entry.attr,
&queue_logical_block_size_entry.attr,
+ &queue_physical_block_size_entry.attr,
+ &queue_io_min_entry.attr,
+ &queue_io_opt_entry.attr,
&queue_nonrot_entry.attr,
&queue_nomerges_entry.attr,
&queue_rq_affinity_entry.attr,
diff --git a/block/genhd.c b/block/genhd.c
index 1a4916e..aa9ce4a 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -852,11 +852,20 @@ static ssize_t disk_capability_show(struct device *dev,
return sprintf(buf, "%x\n", disk->flags);
}
+static ssize_t disk_alignment_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+
+ return sprintf(buf, "%d\n", queue_io_alignment(disk->queue));
+}
+
static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
+static DEVICE_ATTR(alignment, S_IRUGO, disk_alignment_show, NULL);
static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
#ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -875,6 +884,7 @@ static struct attribute *disk_attrs[] = {
&dev_attr_removable.attr,
&dev_attr_ro.attr,
&dev_attr_size.attr,
+ &dev_attr_alignment.attr,
&dev_attr_capability.attr,
&dev_attr_stat.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 99e33ef..aca742b 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -219,6 +219,13 @@ ssize_t part_size_show(struct device *dev,
return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects);
}
+ssize_t part_alignment_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct hd_struct *p = dev_to_part(dev);
+ return sprintf(buf, "%llu\n", (unsigned long long)p->alignment);
+}
+
ssize_t part_stat_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -272,6 +279,7 @@ ssize_t part_fail_store(struct device *dev,
static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL);
static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
+static DEVICE_ATTR(alignment, S_IRUGO, part_alignment_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
#ifdef CONFIG_FAIL_MAKE_REQUEST
static struct device_attribute dev_attr_fail =
@@ -282,6 +290,7 @@ static struct attribute *part_attrs[] = {
&dev_attr_partition.attr,
&dev_attr_start.attr,
&dev_attr_size.attr,
+ &dev_attr_alignment.attr,
&dev_attr_stat.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&dev_attr_fail.attr,
@@ -383,6 +392,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
pdev = part_to_dev(p);
p->start_sect = start;
+ p->alignment = queue_sector_alignment(disk->queue, start);
p->nr_sects = len;
p->partno = partno;
p->policy = get_disk_ro(disk);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2655673..55d19dc 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -314,11 +314,16 @@ struct queue_limits {
unsigned int max_hw_sectors;
unsigned int max_sectors;
unsigned int max_segment_size;
+ unsigned int physical_block_size;
+ unsigned int io_alignment;
+ unsigned int io_min;
+ unsigned int io_opt;
unsigned short logical_block_size;
unsigned short max_hw_segments;
unsigned short max_phys_segments;
+ unsigned char misaligned;
unsigned char no_cluster;
};
@@ -909,6 +914,15 @@ extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_physical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_io_alignment(struct request_queue *q,
+ unsigned int alignment);
+extern void blk_queue_io_min(struct request_queue *q, unsigned int min);
+extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
+extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ sector_t offset);
+extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
+ sector_t offset);
extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
extern void blk_queue_dma_pad(struct request_queue *, unsigned int);
extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int);
@@ -1045,6 +1059,39 @@ static inline unsigned short bdev_logical_block_size(struct block_device *bdev)
return queue_logical_block_size(bdev_get_queue(bdev));
}
+static inline unsigned int queue_physical_block_size(struct request_queue *q)
+{
+ return q->limits.physical_block_size;
+}
+
+static inline unsigned int queue_io_min(struct request_queue *q)
+{
+ return q->limits.io_min;
+}
+
+static inline unsigned int queue_io_opt(struct request_queue *q)
+{
+ return q->limits.io_opt;
+}
+
+static inline int queue_io_alignment(struct request_queue *q)
+{
+ if (q && q->limits.misaligned)
+ return -1;
+
+ if (q && q->limits.io_alignment)
+ return q->limits.io_alignment;
+
+ return 0;
+}
+
+static inline int queue_sector_alignment(struct request_queue *q,
+ sector_t sector)
+{
+ return ((sector << 9) - q->limits.io_alignment)
+ & (q->limits.io_min - 1);
+}
+
static inline int queue_dma_alignment(struct request_queue *q)
{
return q ? q->dma_alignment : 511;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index a1a28ca..6a5d0df 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -90,6 +90,7 @@ struct disk_stats {
struct hd_struct {
sector_t start_sect;
sector_t nr_sects;
+ sector_t alignment;
struct device __dev;
struct kobject *holder_dir;
int policy, partno;
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 06/13] MD: Use new topology calls to indicate alignment and I/O sizes
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (4 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 05/13] block: Export I/O topology for block devices and partitions Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 07/13] block: Deprecate blk_queue_stack_limits Martin K. Petersen
` (6 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Switch MD over to the new disk_stack_limits() function which checks for
aligment and adjusts preferred I/O sizes when stacking.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/md/linear.c | 3 +--
drivers/md/multipath.c | 5 ++---
drivers/md/raid0.c | 8 ++++++--
drivers/md/raid1.c | 9 ++++-----
drivers/md/raid10.c | 13 ++++++++-----
drivers/md/raid5.c | 11 +++++++++++
6 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 64f1f3e..cc92e07 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -138,9 +138,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
}
disk->rdev = rdev;
+ disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset);
- blk_queue_stack_limits(mddev->queue,
- rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 4ee31aa..90e160d 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -294,7 +294,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
for (path = first; path <= last; path++)
if ((p=conf->multipaths+path)->rdev == NULL) {
q = rdev->bdev->bd_disk->queue;
- blk_queue_stack_limits(mddev->queue, q);
+ disk_stack_limits(mddev->gendisk, rdev->bdev, 0);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
@@ -460,9 +460,8 @@ static int multipath_run (mddev_t *mddev)
disk = conf->multipaths + disk_idx;
disk->rdev = rdev;
+ disk_stack_limits(mddev->gendisk, rdev->bdev, 0);
- blk_queue_stack_limits(mddev->queue,
- rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, not that we ever expect a device with
* a merge_bvec_fn to be involved in multipath */
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 925507e..02885fc 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -120,6 +120,10 @@ static int create_strip_zones (mddev_t *mddev)
zone = &conf->strip_zone[0];
cnt = 0;
smallest = NULL;
+
+ blk_queue_io_min(mddev->queue, mddev->chunk_size);
+ blk_queue_io_opt(mddev->queue, mddev->chunk_size * mddev->raid_disks);
+
zone->dev = conf->devlist;
list_for_each_entry(rdev1, &mddev->disks, same_set) {
int j = rdev1->raid_disk;
@@ -136,8 +140,8 @@ static int create_strip_zones (mddev_t *mddev)
}
zone->dev[j] = rdev1;
- blk_queue_stack_limits(mddev->queue,
- rdev1->bdev->bd_disk->queue);
+ disk_stack_limits(mddev->gendisk, rdev1->bdev,
+ rdev1->data_offset);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e23758b..ac50039 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1123,8 +1123,8 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
for (mirror = first; mirror <= last; mirror++)
if ( !(p=conf->mirrors+mirror)->rdev) {
- blk_queue_stack_limits(mddev->queue,
- rdev->bdev->bd_disk->queue);
+ disk_stack_limits(mddev->gendisk, rdev->bdev,
+ rdev->data_offset);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
@@ -1988,9 +1988,8 @@ static int run(mddev_t *mddev)
disk = conf->mirrors + disk_idx;
disk->rdev = rdev;
-
- blk_queue_stack_limits(mddev->queue,
- rdev->bdev->bd_disk->queue);
+ disk_stack_limits(mddev->gendisk, rdev->bdev,
+ rdev->data_offset);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1a41aea..bf19876 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1151,8 +1151,8 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
for ( ; mirror <= last ; mirror++)
if ( !(p=conf->mirrors+mirror)->rdev) {
- blk_queue_stack_limits(mddev->queue,
- rdev->bdev->bd_disk->queue);
+ disk_stack_limits(mddev->gendisk, rdev->bdev,
+ rdev->data_offset);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
@@ -2129,6 +2129,10 @@ static int run(mddev_t *mddev)
spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock;
+ blk_queue_io_min(mddev->queue, mddev->chunk_size);
+ blk_queue_io_opt(mddev->queue,
+ (mddev->chunk_size * mddev->raid_disks) >> 1);
+
list_for_each_entry(rdev, &mddev->disks, same_set) {
disk_idx = rdev->raid_disk;
if (disk_idx >= mddev->raid_disks
@@ -2137,9 +2141,8 @@ static int run(mddev_t *mddev)
disk = conf->mirrors + disk_idx;
disk->rdev = rdev;
-
- blk_queue_stack_limits(mddev->queue,
- rdev->bdev->bd_disk->queue);
+ disk_stack_limits(mddev->gendisk, rdev->bdev,
+ rdev->data_offset);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 7970dc8..a389c11 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4601,6 +4601,17 @@ static int run(mddev_t *mddev)
md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
+ blk_queue_io_min(mddev->queue, mddev->chunk_size);
+
+ if (mddev->level == 5)
+ blk_queue_io_opt(mddev->queue,
+ mddev->chunk_size * (mddev->raid_disks - 1));
+ else
+ blk_queue_io_opt(mddev->queue,
+ mddev->chunk_size * (mddev->raid_disks - 2));
+
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset);
return 0;
abort:
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 07/13] block: Deprecate blk_queue_stack_limits
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (5 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 06/13] MD: Use new topology calls to indicate alignment and I/O sizes Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 08/13] sd: Physical block size and alignment support Martin K. Petersen
` (5 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
blk_queue_stack_limits() has been replaced by blk_stack_limits() and
disk_stack_limits() and can be removed.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
block/blk-settings.c | 40 ----------------------------------------
include/linux/blkdev.h | 1 -
2 files changed, 0 insertions(+), 41 deletions(-)
diff --git a/block/blk-settings.c b/block/blk-settings.c
index aea6762..001ab8d 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -402,46 +402,6 @@ EXPORT_SYMBOL(blk_queue_io_opt);
#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
/**
- * blk_queue_stack_limits - inherit underlying queue limits for stacked drivers
- * @t: the stacking driver (top)
- * @b: the underlying device (bottom)
- **/
-void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
-{
- /* zero is "infinity" */
- t->limits.max_sectors = min_not_zero(queue_max_sectors(t),
- queue_max_sectors(b));
-
- t->limits.max_hw_sectors = min_not_zero(queue_max_hw_sectors(t),
- queue_max_hw_sectors(b));
-
- t->limits.seg_boundary_mask = min_not_zero(queue_segment_boundary(t),
- queue_segment_boundary(b));
-
- t->limits.max_phys_segments = min_not_zero(queue_max_phys_segments(t),
- queue_max_phys_segments(b));
-
- t->limits.max_hw_segments = min_not_zero(queue_max_hw_segments(t),
- queue_max_hw_segments(b));
-
- t->limits.max_segment_size = min_not_zero(queue_max_segment_size(t),
- queue_max_segment_size(b));
-
- t->limits.logical_block_size = max(queue_logical_block_size(t),
- queue_logical_block_size(b));
-
- if (!t->queue_lock)
- WARN_ON_ONCE(1);
- else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
- unsigned long flags;
- spin_lock_irqsave(t->queue_lock, flags);
- queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
- spin_unlock_irqrestore(t->queue_lock, flags);
- }
-}
-EXPORT_SYMBOL(blk_queue_stack_limits);
-
-/**
* blk_stack_limits - adjust queue_limits for stacked devices
* @t: the stacking driver limits (top)
* @bdev: the underlying queue limits (bottom)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 55d19dc..df5a8cd 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -923,7 +923,6 @@ extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
sector_t offset);
extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
sector_t offset);
-extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
extern void blk_queue_dma_pad(struct request_queue *, unsigned int);
extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int);
extern int blk_queue_dma_drain(struct request_queue *q,
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 08/13] sd: Physical block size and alignment support
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (6 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 07/13] block: Deprecate blk_queue_stack_limits Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 09/13] sd: Detect non-rotational devices Martin K. Petersen
` (4 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Extract physical block size and lowest aligned LBA from READ
CAPACITY(16) response and adjust queue parameters.
Report physical block size and alignment when applicable.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/scsi/sd.c | 23 +++++++++++++++++++++--
drivers/scsi/sd.h | 1 +
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index c3afcae..86a8b12 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1306,6 +1306,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
int sense_valid = 0;
int the_result;
int retries = 3;
+ unsigned int alignment;
unsigned long long lba;
unsigned sector_size;
@@ -1346,6 +1347,16 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
sector_size = (buffer[8] << 24) | (buffer[9] << 16) |
(buffer[10] << 8) | buffer[11];
+
+ /* Logical blocks per physical block exponent */
+ sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size;
+
+ /* Lowest aligned logical block */
+ alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
+ blk_queue_io_alignment(sdp->request_queue, alignment);
+ if (alignment && sdkp->first_scan)
+ sd_printk(KERN_NOTICE, sdkp, "%u-byte alignment\n", alignment);
+
lba = (((u64)buffer[0] << 56) | ((u64)buffer[1] << 48) |
((u64)buffer[2] << 40) | ((u64)buffer[3] << 32) |
((u64)buffer[4] << 24) | ((u64)buffer[5] << 16) |
@@ -1402,6 +1413,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
sector_size = (buffer[4] << 24) | (buffer[5] << 16) |
(buffer[6] << 8) | buffer[7];
+ sdkp->hw_sector_size = sector_size;
lba = (buffer[0] << 24) | (buffer[1] << 16) |
(buffer[2] << 8) | buffer[3];
@@ -1526,11 +1538,17 @@ got_data:
string_get_size(sz, STRING_UNITS_10, cap_str_10,
sizeof(cap_str_10));
- if (sdkp->first_scan || old_capacity != sdkp->capacity)
+ if (sdkp->first_scan || old_capacity != sdkp->capacity) {
sd_printk(KERN_NOTICE, sdkp,
- "%llu %d-byte hardware sectors: (%s/%s)\n",
+ "%llu %d-byte logical blocks: (%s/%s)\n",
(unsigned long long)sdkp->capacity,
sector_size, cap_str_10, cap_str_2);
+
+ if (sdkp->hw_sector_size != sector_size)
+ sd_printk(KERN_NOTICE, sdkp,
+ "%u-byte physical blocks\n",
+ sdkp->hw_sector_size);
+ }
}
/* Rescale capacity to 512-byte units */
@@ -1543,6 +1561,7 @@ got_data:
else if (sector_size == 256)
sdkp->capacity >>= 1;
+ blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size);
sdkp->device->sector_size = sector_size;
}
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 708778c..8474b5b 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -45,6 +45,7 @@ struct scsi_disk {
unsigned int openers; /* protected by BKL for now, yuck */
sector_t capacity; /* size in 512-byte sectors */
u32 index;
+ unsigned short hw_sector_size;
u8 media_present;
u8 write_prot;
u8 protection_type;/* Data Integrity Field */
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 09/13] sd: Detect non-rotational devices
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (7 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 08/13] sd: Physical block size and alignment support Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 10/13] sd: Block limits VPD support Martin K. Petersen
` (3 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Detect non-rotational devices and set the queue flag accordingly.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/scsi/sd.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 86a8b12..ee61136 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -50,6 +50,7 @@
#include <linux/string_helpers.h>
#include <linux/async.h>
#include <asm/uaccess.h>
+#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -1800,6 +1801,29 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
}
/**
+ * sd_read_block_characteristics - Query block dev. characteristics
+ * @disk: disk to query
+ */
+static void sd_read_block_characteristics(struct scsi_disk *sdkp)
+{
+ char *buffer;
+ u16 rot;
+
+ /* Block Device Characteristics VPD */
+ buffer = scsi_get_vpd_page(sdkp->device, 0xb1);
+
+ if (buffer == NULL)
+ return;
+
+ rot = get_unaligned_be16(&buffer[4]);
+
+ if (rot == 1)
+ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue);
+
+ kfree(buffer);
+}
+
+/**
* sd_revalidate_disk - called the first time a new disk is seen,
* performs disk spin up, read_capacity, etc.
* @disk: struct gendisk we care about
@@ -1836,6 +1860,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
*/
if (sdkp->media_present) {
sd_read_capacity(sdkp, buffer);
+ sd_read_block_characteristics(sdkp);
sd_read_write_protect_flag(sdkp, buffer);
sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer);
@@ -1976,6 +2001,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
add_disk(gd);
sd_dif_config_host(sdkp);
+ sd_revalidate_disk(gd);
+
sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
sdp->removable ? "removable " : "");
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 10/13] sd: Block limits VPD support
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (8 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 09/13] sd: Detect non-rotational devices Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 11/13] scsi_debug: Add support for physical block exponent and alignment Martin K. Petersen
` (2 subsequent siblings)
12 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
Query the block limits VPD page and adjust queue minimum and optimal I/O
sizes.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/scsi/sd.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index ee61136..6bdf931 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1801,6 +1801,29 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
}
/**
+ * sd_read_block_limits - Query disk device for preferred I/O sizes.
+ * @disk: disk to query
+ */
+static void sd_read_block_limits(struct scsi_disk *sdkp)
+{
+ unsigned int sector_sz = sdkp->device->sector_size;
+ char *buffer;
+
+ /* Block Limits VPD */
+ buffer = scsi_get_vpd_page(sdkp->device, 0xb0);
+
+ if (buffer == NULL)
+ return;
+
+ blk_queue_io_min(sdkp->disk->queue,
+ get_unaligned_be16(&buffer[6]) * sector_sz);
+ blk_queue_io_opt(sdkp->disk->queue,
+ get_unaligned_be32(&buffer[12]) * sector_sz);
+
+ kfree(buffer);
+}
+
+/**
* sd_read_block_characteristics - Query block dev. characteristics
* @disk: disk to query
*/
@@ -1860,6 +1883,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
*/
if (sdkp->media_present) {
sd_read_capacity(sdkp, buffer);
+ sd_read_block_limits(sdkp);
sd_read_block_characteristics(sdkp);
sd_read_write_protect_flag(sdkp, buffer);
sd_read_cache_type(sdkp, buffer);
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 11/13] scsi_debug: Add support for physical block exponent and alignment
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (9 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 10/13] sd: Block limits VPD support Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-19 15:11 ` Douglas Gilbert
2009-05-15 4:40 ` [PATCH 12/13] libata: Report disk alignment and physical block size Martin K. Petersen
2009-05-15 4:40 ` [PATCH 13/13] libata: Media rotation rate and form factor heuristics Martin K. Petersen
12 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
This patch adds support for setting the physical block exponent and
lowest aligned LBA in the READ CAPACITY(16) response.
The B0 VPD page is adjusted accordingly.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/scsi/scsi_debug.c | 30 +++++++++++++++++++++++++++++-
1 files changed, 29 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 213123b..f0198e0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -101,6 +101,8 @@ static const char * scsi_debug_version_date = "20070104";
#define DEF_DIF 0
#define DEF_GUARD 0
#define DEF_ATO 1
+#define DEF_PHYSBLK_EXP 0
+#define DEF_LOWEST_ALIGNED 0
/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1
@@ -156,6 +158,8 @@ static int scsi_debug_dix = DEF_DIX;
static int scsi_debug_dif = DEF_DIF;
static int scsi_debug_guard = DEF_GUARD;
static int scsi_debug_ato = DEF_ATO;
+static int scsi_debug_physblk_exp = DEF_PHYSBLK_EXP;
+static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED;
static int scsi_debug_cmnd_count = 0;
@@ -657,7 +661,12 @@ static unsigned char vpdb0_data[] = {
static int inquiry_evpd_b0(unsigned char * arr)
{
+ unsigned int gran;
+
memcpy(arr, vpdb0_data, sizeof(vpdb0_data));
+ gran = 1 << scsi_debug_physblk_exp;
+ arr[2] = (gran >> 8) & 0xff;
+ arr[3] = gran & 0xff;
if (sdebug_store_sectors > 0x400) {
arr[4] = (sdebug_store_sectors >> 24) & 0xff;
arr[5] = (sdebug_store_sectors >> 16) & 0xff;
@@ -945,6 +954,9 @@ static int resp_readcap16(struct scsi_cmnd * scp,
arr[9] = (scsi_debug_sector_size >> 16) & 0xff;
arr[10] = (scsi_debug_sector_size >> 8) & 0xff;
arr[11] = scsi_debug_sector_size & 0xff;
+ arr[13] = scsi_debug_physblk_exp & 0xf;
+ arr[14] = (scsi_debug_lowest_aligned >> 8) & 0x3f;
+ arr[15] = scsi_debug_lowest_aligned & 0xff;
if (scsi_debug_dif) {
arr[12] = (scsi_debug_dif - 1) << 1; /* P_TYPE */
@@ -2380,6 +2392,8 @@ module_param_named(dix, scsi_debug_dix, int, S_IRUGO);
module_param_named(dif, scsi_debug_dif, int, S_IRUGO);
module_param_named(guard, scsi_debug_guard, int, S_IRUGO);
module_param_named(ato, scsi_debug_ato, int, S_IRUGO);
+module_param_named(physblk_exp, scsi_debug_physblk_exp, int, S_IRUGO);
+module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO);
MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
MODULE_DESCRIPTION("SCSI debug adapter driver");
@@ -2401,7 +2415,9 @@ MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)");
-MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)");
+MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)");
+MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)");
+MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)");
MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)");
MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)");
MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)");
@@ -2874,6 +2890,18 @@ static int __init scsi_debug_init(void)
return -EINVAL;
}
+ if (scsi_debug_physblk_exp > 15) {
+ printk(KERN_ERR "scsi_debug_init: invalid physblk_exp %u\n",
+ scsi_debug_physblk_exp);
+ return -EINVAL;
+ }
+
+ if (scsi_debug_lowest_aligned > 0x3fff) {
+ printk(KERN_ERR "scsi_debug_init: lowest_aligned too big: %u\n",
+ scsi_debug_lowest_aligned);
+ return -EINVAL;
+ }
+
if (scsi_debug_dev_size_mb < 1)
scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
sz = (unsigned long)scsi_debug_dev_size_mb * 1048576;
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 12/13] libata: Report disk alignment and physical block size
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (10 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 11/13] scsi_debug: Add support for physical block exponent and alignment Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 18:17 ` Jeff Garzik
2009-05-15 4:40 ` [PATCH 13/13] libata: Media rotation rate and form factor heuristics Martin K. Petersen
12 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
For disks with 4KB sectors, report the correct block size and alignment
when filling out the READ CAPACITY(16) response.
This patch is based upon code from Matthew Wilcox' 4KB ATA tree. I
fixed the bug I reported a while back caused by ATA and SCSI using
different approaches to describing the alignment.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/ata/libata-scsi.c | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 6e4c600..5072003 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2376,7 +2376,23 @@ saving_not_supp:
*/
static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
{
- u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
+ struct ata_device *dev = args->dev;
+ u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
+ u8 log_per_phys = 0;
+ u16 lowest_aligned = 0;
+ u16 word_106 = dev->id[106];
+ u16 word_209 = dev->id[209];
+
+ if ((word_106 & 0xc000) == 0x4000) {
+ /* Number and offset of logical sectors per physical sector */
+ if (word_106 & (1 << 13))
+ log_per_phys = word_106 & 0xf;
+ if ((word_209 & 0xc000) == 0x4000) {
+ u16 first = dev->id[209] & 0x3fff;
+ if (first > 0)
+ lowest_aligned = (1 << log_per_phys) - first;
+ }
+ }
VPRINTK("ENTER\n");
@@ -2407,6 +2423,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
/* sector size */
rbuf[10] = ATA_SECT_SIZE >> 8;
rbuf[11] = ATA_SECT_SIZE & 0xff;
+
+ rbuf[12] = 0;
+ rbuf[13] = log_per_phys;
+ rbuf[14] = (lowest_aligned >> 8) & 0x3f;
+ rbuf[15] = lowest_aligned;
}
return 0;
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 13/13] libata: Media rotation rate and form factor heuristics
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
` (11 preceding siblings ...)
2009-05-15 4:40 ` [PATCH 12/13] libata: Report disk alignment and physical block size Martin K. Petersen
@ 2009-05-15 4:40 ` Martin K. Petersen
2009-05-15 18:17 ` Jeff Garzik
12 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-15 4:40 UTC (permalink / raw)
To: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Cc: Martin K. Petersen
From: Martin K. Petersen <martin.petersen@oracle.com>
This patch delegates setting the queue NONROT flag to SCSI.
It also provides new heuristics for parsing both the form factor and
media rotation rate ATA IDENFITY words.
The reported ATA version must be 7 or greater and the device must return
values defined as valid in the standard. Only then are the
characteristics reported to SCSI via the VPD B1 page.
This seems like a reasonable compromise to me considering that we have
been shipping several kernel releases that key off the rotation rate bit
without any version checking whatsoever. With no complaints so far.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
drivers/ata/libata-scsi.c | 15 ++++++---------
include/linux/ata.h | 28 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 5072003..0244846 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1119,10 +1119,6 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
} else {
- if (ata_id_is_ssd(dev->id))
- queue_flag_set_unlocked(QUEUE_FLAG_NONROT,
- sdev->request_queue);
-
/* ATA devices must be sector aligned */
blk_queue_update_dma_alignment(sdev->request_queue,
ATA_SECT_SIZE - 1);
@@ -2142,13 +2138,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
{
+ int form_factor = ata_id_form_factor(args->id);
+ int media_rotation_rate = ata_id_rotation_rate(args->id);
+
rbuf[1] = 0xb1;
rbuf[3] = 0x3c;
- if (ata_id_major_version(args->id) > 7) {
- rbuf[4] = args->id[217] >> 8;
- rbuf[5] = args->id[217];
- rbuf[7] = args->id[168] & 0xf;
- }
+ rbuf[4] = media_rotation_rate >> 8;
+ rbuf[5] = media_rotation_rate;
+ rbuf[7] = form_factor;
return 0;
}
diff --git a/include/linux/ata.h b/include/linux/ata.h
index cb79b7a..915da43 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -730,6 +730,34 @@ static inline int ata_id_has_unload(const u16 *id)
return 0;
}
+static inline int ata_id_form_factor(const u16 *id)
+{
+ u16 val = id[168];
+
+ if (ata_id_major_version(id) < 7 || val == 0 || val == 0xffff)
+ return 0;
+
+ val &= 0xf;
+
+ if (val > 5)
+ return 0;
+
+ return val;
+}
+
+static inline int ata_id_rotation_rate(const u16 *id)
+{
+ u16 val = id[217];
+
+ if (ata_id_major_version(id) < 7 || val == 0 || val == 0xffff)
+ return 0;
+
+ if (val > 1 && val < 0x401)
+ return 0;
+
+ return val;
+}
+
static inline int ata_id_has_trim(const u16 *id)
{
if (ata_id_major_version(id) >= 7 &&
--
1.6.0.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 12/13] libata: Report disk alignment and physical block size
2009-05-15 4:40 ` [PATCH 12/13] libata: Report disk alignment and physical block size Martin K. Petersen
@ 2009-05-15 18:17 ` Jeff Garzik
0 siblings, 0 replies; 32+ messages in thread
From: Jeff Garzik @ 2009-05-15 18:17 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, snitzer, neilb, James.Bottomley, jens.axboe, linux-ide,
linux-scsi
Martin K. Petersen wrote:
> From: Martin K. Petersen <martin.petersen@oracle.com>
>
> For disks with 4KB sectors, report the correct block size and alignment
> when filling out the READ CAPACITY(16) response.
>
> This patch is based upon code from Matthew Wilcox' 4KB ATA tree. I
> fixed the bug I reported a while back caused by ATA and SCSI using
> different approaches to describing the alignment.
>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> ---
> drivers/ata/libata-scsi.c | 23 ++++++++++++++++++++++-
> 1 files changed, 22 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 6e4c600..5072003 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -2376,7 +2376,23 @@ saving_not_supp:
> */
> static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
> {
> - u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
> + struct ata_device *dev = args->dev;
> + u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
> + u8 log_per_phys = 0;
> + u16 lowest_aligned = 0;
> + u16 word_106 = dev->id[106];
> + u16 word_209 = dev->id[209];
> +
> + if ((word_106 & 0xc000) == 0x4000) {
> + /* Number and offset of logical sectors per physical sector */
> + if (word_106 & (1 << 13))
> + log_per_phys = word_106 & 0xf;
> + if ((word_209 & 0xc000) == 0x4000) {
> + u16 first = dev->id[209] & 0x3fff;
> + if (first > 0)
> + lowest_aligned = (1 << log_per_phys) - first;
> + }
> + }
>
> VPRINTK("ENTER\n");
>
> @@ -2407,6 +2423,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
> /* sector size */
> rbuf[10] = ATA_SECT_SIZE >> 8;
> rbuf[11] = ATA_SECT_SIZE & 0xff;
> +
> + rbuf[12] = 0;
> + rbuf[13] = log_per_phys;
> + rbuf[14] = (lowest_aligned >> 8) & 0x3f;
> + rbuf[15] = lowest_aligned;
applied
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 13/13] libata: Media rotation rate and form factor heuristics
2009-05-15 4:40 ` [PATCH 13/13] libata: Media rotation rate and form factor heuristics Martin K. Petersen
@ 2009-05-15 18:17 ` Jeff Garzik
0 siblings, 0 replies; 32+ messages in thread
From: Jeff Garzik @ 2009-05-15 18:17 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, snitzer, neilb, James.Bottomley, jens.axboe, linux-ide,
linux-scsi
Martin K. Petersen wrote:
> From: Martin K. Petersen <martin.petersen@oracle.com>
>
> This patch provides new heuristics for parsing both the form factor and
> media rotation rate ATA IDENFITY words.
>
> The reported ATA version must be 7 or greater and the device must return
> values defined as valid in the standard. Only then are the
> characteristics reported to SCSI via the VPD B1 page.
>
> This seems like a reasonable compromise to me considering that we have
> been shipping several kernel releases that key off the rotation rate bit
> without any version checking whatsoever. With no complaints so far.
>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> ---
> drivers/ata/libata-scsi.c | 15 ++++++---------
> include/linux/ata.h | 28 ++++++++++++++++++++++++++++
> 2 files changed, 34 insertions(+), 9 deletions(-)
applied, after dropping the NONROT bit as inappropriate for 2.6.30-rc
(which is where I applied the rest)
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-15 4:40 ` [PATCH 05/13] block: Export I/O topology for block devices and partitions Martin K. Petersen
@ 2009-05-18 17:57 ` Jens Axboe
2009-05-18 18:12 ` Mike Snitzer
0 siblings, 1 reply; 32+ messages in thread
From: Jens Axboe @ 2009-05-18 17:57 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, snitzer, jeff, neilb, James.Bottomley, linux-ide,
linux-scsi
On Fri, May 15 2009, Martin K. Petersen wrote:
> From: Martin K. Petersen <martin.petersen@oracle.com>
>
> To support devices with physical block sizes bigger than 512 bytes we
> need to ensure proper alignment. This patch adds support for exposing
> I/O topology characteristics as devices are stacked.
>
> logical_block_size is the smallest unit the device can address.
>
> physical_block_size indicates the smallest I/O the device can write
> without incurring a read-modify-write penalty.
>
> The io_min parameter is the smallest preferred I/O size reported by
> the device. In many cases this is the same as the physical block
> size. However, the io_min parameter can be scaled up when stacking
> (RAID5 chunk size > physical block size).
>
> The io_opt characteristic indicates the optimal I/O size reported by
> the device. This is usually the stripe width for arrays.
>
> The io_alignment parameter indicates the number of bytes the start of
> the device/partition is offset from the device's natural alignment.
> Partition tools and MD/DM utilities can use this to pad their offsets
> so filesystem start on proper boundaries.
>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> ---
> Documentation/ABI/testing/sysfs-block | 59 +++++++++++
> block/blk-settings.c | 184 +++++++++++++++++++++++++++++++++
> block/blk-sysfs.c | 33 ++++++
> block/genhd.c | 10 ++
> fs/partitions/check.c | 10 ++
> include/linux/blkdev.h | 47 +++++++++
> include/linux/genhd.h | 1 +
> 7 files changed, 344 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
> index 44f52a4..93075cf 100644
> --- a/Documentation/ABI/testing/sysfs-block
> +++ b/Documentation/ABI/testing/sysfs-block
> @@ -60,3 +60,62 @@ Description:
> Indicates whether the block layer should automatically
> generate checksums for write requests bound for
> devices that support receiving integrity metadata.
> +
> +What: /sys/block/<disk>/alignment
> +Date: April 2009
> +Contact: Martin K. Petersen <martin.petersen@oracle.com>
> +Description:
> + Storage devices may report a physical block size that is
> + bigger than the logical block size (for instance a drive
> + with 4KB physical sectors exposing 512-byte logical
> + blocks to the operating system). This parameter
> + indicates how many bytes the beginning of the device is
> + offset from the disk's natural alignment.
> +
> +What: /sys/block/<disk>/<partition>/alignment
> +Date: April 2009
> +Contact: Martin K. Petersen <martin.petersen@oracle.com>
> +Description:
> + Storage devices may report a physical block size that is
> + bigger than the logical block size (for instance a drive
> + with 4KB physical sectors exposing 512-byte logical
> + blocks to the operating system). This parameter
> + indicates how many bytes the beginning of the partition
> + is offset from the disk's natural alignment.
I really hate the 'alignment' name, nobody will know wtf that is without
looking it up. The rest of the names are fairly self explanatory.
offset? offset_size? misalignment? Not very good with names, but perhaps
we can find something more appropriate :-)
The rest of the patch set looks ok to me, if we can just agree on a
silly name, then lets merge it for 2.6.31.
--
Jens Axboe
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-18 17:57 ` Jens Axboe
@ 2009-05-18 18:12 ` Mike Snitzer
2009-05-19 16:41 ` Martin K. Petersen
0 siblings, 1 reply; 32+ messages in thread
From: Mike Snitzer @ 2009-05-18 18:12 UTC (permalink / raw)
To: Jens Axboe
Cc: Martin K. Petersen, rwheeler, jeff, neilb, James.Bottomley,
linux-ide, linux-scsi
On Mon, May 18 2009 at 1:57pm -0400,
Jens Axboe <jens.axboe@oracle.com> wrote:
> On Fri, May 15 2009, Martin K. Petersen wrote:
> > From: Martin K. Petersen <martin.petersen@oracle.com>
> >
> > To support devices with physical block sizes bigger than 512 bytes we
> > need to ensure proper alignment. This patch adds support for exposing
> > I/O topology characteristics as devices are stacked.
> >
> > logical_block_size is the smallest unit the device can address.
> >
> > physical_block_size indicates the smallest I/O the device can write
> > without incurring a read-modify-write penalty.
> >
> > The io_min parameter is the smallest preferred I/O size reported by
> > the device. In many cases this is the same as the physical block
> > size. However, the io_min parameter can be scaled up when stacking
> > (RAID5 chunk size > physical block size).
> >
> > The io_opt characteristic indicates the optimal I/O size reported by
> > the device. This is usually the stripe width for arrays.
> >
> > The io_alignment parameter indicates the number of bytes the start of
> > the device/partition is offset from the device's natural alignment.
> > Partition tools and MD/DM utilities can use this to pad their offsets
> > so filesystem start on proper boundaries.
> >
> > Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> > ---
> > Documentation/ABI/testing/sysfs-block | 59 +++++++++++
> > block/blk-settings.c | 184 +++++++++++++++++++++++++++++++++
> > block/blk-sysfs.c | 33 ++++++
> > block/genhd.c | 10 ++
> > fs/partitions/check.c | 10 ++
> > include/linux/blkdev.h | 47 +++++++++
> > include/linux/genhd.h | 1 +
> > 7 files changed, 344 insertions(+), 0 deletions(-)
> >
> > diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
> > index 44f52a4..93075cf 100644
> > --- a/Documentation/ABI/testing/sysfs-block
> > +++ b/Documentation/ABI/testing/sysfs-block
> > @@ -60,3 +60,62 @@ Description:
> > Indicates whether the block layer should automatically
> > generate checksums for write requests bound for
> > devices that support receiving integrity metadata.
> > +
> > +What: /sys/block/<disk>/alignment
> > +Date: April 2009
> > +Contact: Martin K. Petersen <martin.petersen@oracle.com>
> > +Description:
> > + Storage devices may report a physical block size that is
> > + bigger than the logical block size (for instance a drive
> > + with 4KB physical sectors exposing 512-byte logical
> > + blocks to the operating system). This parameter
> > + indicates how many bytes the beginning of the device is
> > + offset from the disk's natural alignment.
> > +
> > +What: /sys/block/<disk>/<partition>/alignment
> > +Date: April 2009
> > +Contact: Martin K. Petersen <martin.petersen@oracle.com>
> > +Description:
> > + Storage devices may report a physical block size that is
> > + bigger than the logical block size (for instance a drive
> > + with 4KB physical sectors exposing 512-byte logical
> > + blocks to the operating system). This parameter
> > + indicates how many bytes the beginning of the partition
> > + is offset from the disk's natural alignment.
>
> I really hate the 'alignment' name, nobody will know wtf that is without
> looking it up. The rest of the names are fairly self explanatory.
> offset? offset_size? misalignment? Not very good with names, but perhaps
> we can find something more appropriate :-)
>
> The rest of the patch set looks ok to me, if we can just agree on a
> silly name, then lets merge it for 2.6.31.
I agree that 'alignment' is too terse/confusing given that it is an
offset we're exposing. How about 'alignment_offset'?
Mike
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 03/13] block: Move queue limits to an embedded struct
2009-05-15 4:40 ` [PATCH 03/13] block: Move queue limits to an embedded struct Martin K. Petersen
@ 2009-05-18 18:50 ` Mike Snitzer
2009-05-18 18:52 ` Mike Snitzer
2009-05-19 16:46 ` Martin K. Petersen
0 siblings, 2 replies; 32+ messages in thread
From: Mike Snitzer @ 2009-05-18 18:50 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, jeff, neilb, James.Bottomley, jens.axboe, linux-ide,
linux-scsi, agk
On Fri, May 15 2009 at 12:40am -0400,
Martin K. Petersen <martin.petersen@oracle.com> wrote:
> From: Martin K. Petersen <martin.petersen@oracle.com>
>
> To accommodate stacking drivers that do not have an associated request
> queue we're moving the limits to a separate, embedded structure.
Given DM motivated this change, any reason you held off including the
associated DM changes (in a separate patch in the series)? Your initial
DM patch looked reasonable.
On some level leaving that patch out of the series prevents reviewers
the opportunity to really see why a separate 'queue_limits' structure is
even needed. The follow-up question being: is the topology
infrastructure adequately equipped to support DM? I think so
but having others' review would be nice.
Are you looking for such DM changes to be submitted through Alasdair's
tree _after_ your changes go upstream through Jens' tree?
Regards,
Mike
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 03/13] block: Move queue limits to an embedded struct
2009-05-18 18:50 ` Mike Snitzer
@ 2009-05-18 18:52 ` Mike Snitzer
2009-05-19 16:46 ` Martin K. Petersen
1 sibling, 0 replies; 32+ messages in thread
From: Mike Snitzer @ 2009-05-18 18:52 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, jeff, neilb, James.Bottomley, jens.axboe, linux-ide,
linux-scsi, agk
On Mon, May 18 2009 at 2:50pm -0400,
Mike Snitzer <snitzer@redhat.com> wrote:
> On Fri, May 15 2009 at 12:40am -0400,
> Martin K. Petersen <martin.petersen@oracle.com> wrote:
>
> > From: Martin K. Petersen <martin.petersen@oracle.com>
> >
> > To accommodate stacking drivers that do not have an associated request
> > queue we're moving the limits to a separate, embedded structure.
>
> Given DM motivated this change, any reason you held off including the
> associated DM changes (in a separate patch in the series)? Your initial
> DM patch looked reasonable.
I forgot to reference the patch in question:
http://mkp.net/code/topology/dm-topology.patch
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 11/13] scsi_debug: Add support for physical block exponent and alignment
2009-05-15 4:40 ` [PATCH 11/13] scsi_debug: Add support for physical block exponent and alignment Martin K. Petersen
@ 2009-05-19 15:11 ` Douglas Gilbert
0 siblings, 0 replies; 32+ messages in thread
From: Douglas Gilbert @ 2009-05-19 15:11 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Martin K. Petersen wrote:
> From: Martin K. Petersen <martin.petersen@oracle.com>
>
> This patch adds support for setting the physical block exponent and
> lowest aligned LBA in the READ CAPACITY(16) response.
>
> The B0 VPD page is adjusted accordingly.
>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-18 18:12 ` Mike Snitzer
@ 2009-05-19 16:41 ` Martin K. Petersen
2009-05-19 18:15 ` Jens Axboe
0 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-19 16:41 UTC (permalink / raw)
To: Mike Snitzer; +Cc: Jens Axboe, linux-ide, linux-scsi
>>>>> "Mike" == Mike Snitzer <snitzer@redhat.com> writes:
>> I really hate the 'alignment' name, nobody will know wtf that is
>> without looking it up. The rest of the names are fairly self
>> explanatory. offset? offset_size? misalignment? Not very good with
>> names, but perhaps we can find something more appropriate :-)
Yeah, it's a tricky thing to convey. And despite all the other
convergence otherwise happening in the standards, T10 and T13 do not
agree how to describe the logical/physical alignment.
Mike> I agree that 'alignment' is too terse/confusing given that it is
Mike> an offset we're exposing. How about 'alignment_offset'?
I thought I had already changed it to alignment_offset like we talked
about a while ago. But I guess that change was only done mentally :)
Jens, are you ok with that name?
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 03/13] block: Move queue limits to an embedded struct
2009-05-18 18:50 ` Mike Snitzer
2009-05-18 18:52 ` Mike Snitzer
@ 2009-05-19 16:46 ` Martin K. Petersen
1 sibling, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-19 16:46 UTC (permalink / raw)
To: Mike Snitzer; +Cc: jens.axboe, linux-ide, linux-scsi, agk
>>>>> "Mike" == Mike Snitzer <snitzer@redhat.com> writes:
Mike> Given DM motivated this change, any reason you held off including
Mike> the associated DM changes (in a separate patch in the series)?
Mike> Your initial DM patch looked reasonable.
It sounded like you and Alasdair had a plan so I left it out.
If you guys are happy with what I did I'm happy to push it.
Mike> Are you looking for such DM changes to be submitted through
Mike> Alasdair's tree _after_ your changes go upstream through Jens'
Mike> tree?
Yeah, it'll have to be a multistage merge. Block will need to hit
first, then SCSI, DM and MD. And after those are in we can nuke the old
stacking function.
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-19 16:41 ` Martin K. Petersen
@ 2009-05-19 18:15 ` Jens Axboe
2009-05-20 21:19 ` Martin K. Petersen
0 siblings, 1 reply; 32+ messages in thread
From: Jens Axboe @ 2009-05-19 18:15 UTC (permalink / raw)
To: Martin K. Petersen; +Cc: Mike Snitzer, linux-ide, linux-scsi
On Tue, May 19 2009, Martin K. Petersen wrote:
> >>>>> "Mike" == Mike Snitzer <snitzer@redhat.com> writes:
>
> >> I really hate the 'alignment' name, nobody will know wtf that is
> >> without looking it up. The rest of the names are fairly self
> >> explanatory. offset? offset_size? misalignment? Not very good with
> >> names, but perhaps we can find something more appropriate :-)
>
> Yeah, it's a tricky thing to convey. And despite all the other
> convergence otherwise happening in the standards, T10 and T13 do not
> agree how to describe the logical/physical alignment.
>
>
> Mike> I agree that 'alignment' is too terse/confusing given that it is
> Mike> an offset we're exposing. How about 'alignment_offset'?
>
> I thought I had already changed it to alignment_offset like we talked
> about a while ago. But I guess that change was only done mentally :)
>
> Jens, are you ok with that name?
I think so, I can't think of anything better :-)
If you repost an updated 5/13 patch and I'll add it to the mix.
--
Jens Axboe
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-19 18:15 ` Jens Axboe
@ 2009-05-20 21:19 ` Martin K. Petersen
2009-05-22 7:30 ` Jens Axboe
0 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-20 21:19 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-ide, linux-scsi
>>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
Jens> If you repost an updated 5/13 patch and I'll add it to the mix.
block: Export I/O topology for block devices and partitions
To support devices with physical block sizes bigger than 512 bytes we
need to ensure proper alignment. This patch adds support for exposing
I/O topology characteristics as devices are stacked.
logical_block_size is the smallest unit the device can address.
physical_block_size indicates the smallest I/O the device can write
without incurring a read-modify-write penalty.
The alignment_offset parameter indicates the number of bytes the start
of the device/partition is offset from the device's natural alignment.
Partition tools and MD/DM utilities can use this to pad their offsets
so filesystems start on proper boundaries.
The io_min parameter is the smallest preferred I/O size reported by
the device. In many cases this is the same as the physical block
size. However, the io_min parameter can be scaled up when stacking
(RAID5 chunk size > physical block size).
The io_opt characteristic indicates the optimal I/O size reported by
the device. This is usually the stripe width for arrays.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
---
diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
index 44f52a4..cbbd3e0 100644
--- a/Documentation/ABI/testing/sysfs-block
+++ b/Documentation/ABI/testing/sysfs-block
@@ -60,3 +60,62 @@ Description:
Indicates whether the block layer should automatically
generate checksums for write requests bound for
devices that support receiving integrity metadata.
+
+What: /sys/block/<disk>/alignment_offset
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report a physical block size that is
+ bigger than the logical block size (for instance a drive
+ with 4KB physical sectors exposing 512-byte logical
+ blocks to the operating system). This parameter
+ indicates how many bytes the beginning of the device is
+ offset from the disk's natural alignment.
+
+What: /sys/block/<disk>/<partition>/alignment_offset
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report a physical block size that is
+ bigger than the logical block size (for instance a drive
+ with 4KB physical sectors exposing 512-byte logical
+ blocks to the operating system). This parameter
+ indicates how many bytes the beginning of the partition
+ is offset from the disk's natural alignment.
+
+What: /sys/block/<disk>/queue/logical_block_size
+Date: May 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ This is the smallest unit the storage device can
+ address. It is typically 512 bytes.
+
+What: /sys/block/<disk>/queue/physical_block_size
+Date: May 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ This is the smallest unit the storage device can write
+ without resorting to read-modify-write operation. It is
+ usually the same as the logical block size but may be
+ bigger. One example is SATA drives with 4KB sectors
+ that expose a 512-byte logical block size to the
+ operating system.
+
+What: /sys/block/<disk>/queue/minimum_io_size
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report a preferred minimum I/O size,
+ which is the smallest request the device can perform
+ without incurring a read-modify-write penalty. For disk
+ drives this is often the physical block size. For RAID
+ arrays it is often the stripe chunk size.
+
+What: /sys/block/<disk>/queue/optimal_io_size
+Date: April 2009
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Storage devices may report an optimal I/O size, which is
+ the device's preferred unit of receiving I/O. This is
+ rarely reported for disk drives. For RAID devices it is
+ usually the stripe width or the internal block size.
diff --git a/block/blk-settings.c b/block/blk-settings.c
index b0f547c..5649f34 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -309,9 +309,94 @@ EXPORT_SYMBOL(blk_queue_max_segment_size);
void blk_queue_logical_block_size(struct request_queue *q, unsigned short size)
{
q->limits.logical_block_size = size;
+
+ if (q->limits.physical_block_size < size)
+ q->limits.physical_block_size = size;
+
+ if (q->limits.io_min < q->limits.physical_block_size)
+ q->limits.io_min = q->limits.physical_block_size;
}
EXPORT_SYMBOL(blk_queue_logical_block_size);
+/**
+ * blk_queue_physical_block_size - set physical block size for the queue
+ * @q: the request queue for the device
+ * @size: the physical block size, in bytes
+ *
+ * Description:
+ * This should be set to the lowest possible sector size that the
+ * hardware can operate on without reverting to read-modify-write
+ * operations.
+ */
+void blk_queue_physical_block_size(struct request_queue *q, unsigned short size)
+{
+ q->limits.physical_block_size = size;
+
+ if (q->limits.physical_block_size < q->limits.logical_block_size)
+ q->limits.physical_block_size = q->limits.logical_block_size;
+
+ if (q->limits.io_min < q->limits.physical_block_size)
+ q->limits.io_min = q->limits.physical_block_size;
+}
+EXPORT_SYMBOL(blk_queue_physical_block_size);
+
+/**
+ * blk_queue_alignment_offset - set physical block alignment offset
+ * @q: the request queue for the device
+ * @alignment: alignment offset in bytes
+ *
+ * Description:
+ * Some devices are naturally misaligned to compensate for things like
+ * the legacy DOS partition table 63-sector offset. Low-level drivers
+ * should call this function for devices whose first sector is not
+ * naturally aligned.
+ */
+void blk_queue_alignment_offset(struct request_queue *q, unsigned int offset)
+{
+ q->limits.alignment_offset =
+ offset & (q->limits.physical_block_size - 1);
+ q->limits.misaligned = 0;
+}
+EXPORT_SYMBOL(blk_queue_alignment_offset);
+
+/**
+ * blk_queue_io_min - set minimum request size for the queue
+ * @q: the request queue for the device
+ * @io_min: smallest I/O size in bytes
+ *
+ * Description:
+ * Some devices have an internal block size bigger than the reported
+ * hardware sector size. This function can be used to signal the
+ * smallest I/O the device can perform without incurring a performance
+ * penalty.
+ */
+void blk_queue_io_min(struct request_queue *q, unsigned int min)
+{
+ q->limits.io_min = min;
+
+ if (q->limits.io_min < q->limits.logical_block_size)
+ q->limits.io_min = q->limits.logical_block_size;
+
+ if (q->limits.io_min < q->limits.physical_block_size)
+ q->limits.io_min = q->limits.physical_block_size;
+}
+EXPORT_SYMBOL(blk_queue_io_min);
+
+/**
+ * blk_queue_io_opt - set optimal request size for the queue
+ * @q: the request queue for the device
+ * @io_opt: optimal request size in bytes
+ *
+ * Description:
+ * Drivers can call this function to set the preferred I/O request
+ * size for devices that report such a value.
+ */
+void blk_queue_io_opt(struct request_queue *q, unsigned int opt)
+{
+ q->limits.io_opt = opt;
+}
+EXPORT_SYMBOL(blk_queue_io_opt);
+
/*
* Returns the minimum that is _not_ zero, unless both are zero.
*/
@@ -358,6 +443,107 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
EXPORT_SYMBOL(blk_queue_stack_limits);
/**
+ * blk_stack_limits - adjust queue_limits for stacked devices
+ * @t: the stacking driver limits (top)
+ * @bdev: the underlying queue limits (bottom)
+ * @offset: offset to beginning of data within component device
+ *
+ * Description:
+ * Merges two queue_limit structs. Returns 0 if alignment didn't
+ * change. Returns -1 if adding the bottom device caused
+ * misalignment.
+ */
+int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ sector_t offset)
+{
+ t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
+ t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
+
+ t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
+ b->seg_boundary_mask);
+
+ t->max_phys_segments = min_not_zero(t->max_phys_segments,
+ b->max_phys_segments);
+
+ t->max_hw_segments = min_not_zero(t->max_hw_segments,
+ b->max_hw_segments);
+
+ t->max_segment_size = min_not_zero(t->max_segment_size,
+ b->max_segment_size);
+
+ t->logical_block_size = max(t->logical_block_size,
+ b->logical_block_size);
+
+ t->physical_block_size = max(t->physical_block_size,
+ b->physical_block_size);
+
+ t->io_min = max(t->io_min, b->io_min);
+ t->no_cluster |= b->no_cluster;
+
+ /* Bottom device offset aligned? */
+ if (offset &&
+ (offset & (b->physical_block_size - 1)) != b->alignment_offset) {
+ t->misaligned = 1;
+ return -1;
+ }
+
+ /* If top has no alignment offset, inherit from bottom */
+ if (!t->alignment_offset)
+ t->alignment_offset =
+ b->alignment_offset & (b->physical_block_size - 1);
+
+ /* Top device aligned on logical block boundary? */
+ if (t->alignment_offset & (t->logical_block_size - 1)) {
+ t->misaligned = 1;
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * disk_stack_limits - adjust queue limits for stacked drivers
+ * @t: MD/DM gendisk (top)
+ * @bdev: the underlying block device (bottom)
+ * @offset: offset to beginning of data within component device
+ *
+ * Description:
+ * Merges the limits for two queues. Returns 0 if alignment
+ * didn't change. Returns -1 if adding the bottom device caused
+ * misalignment.
+ */
+void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
+ sector_t offset)
+{
+ struct request_queue *t = disk->queue;
+ struct request_queue *b = bdev_get_queue(bdev);
+
+ offset += get_start_sect(bdev) << 9;
+
+ if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) {
+ char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
+
+ disk_name(disk, 0, top);
+ bdevname(bdev, bottom);
+
+ printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n",
+ top, bottom);
+ }
+
+ if (!t->queue_lock)
+ WARN_ON_ONCE(1);
+ else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(t->queue_lock, flags);
+ if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
+ queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
+ spin_unlock_irqrestore(t->queue_lock, flags);
+ }
+}
+EXPORT_SYMBOL(disk_stack_limits);
+
+/**
* blk_queue_dma_pad - set pad mask
* @q: the request queue for the device
* @mask: pad mask
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 3ccdadb..9337e17 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -105,6 +105,21 @@ static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page
return queue_var_show(queue_logical_block_size(q), page);
}
+static ssize_t queue_physical_block_size_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_physical_block_size(q), page);
+}
+
+static ssize_t queue_io_min_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_io_min(q), page);
+}
+
+static ssize_t queue_io_opt_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(queue_io_opt(q), page);
+}
+
static ssize_t
queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
{
@@ -257,6 +272,21 @@ static struct queue_sysfs_entry queue_logical_block_size_entry = {
.show = queue_logical_block_size_show,
};
+static struct queue_sysfs_entry queue_physical_block_size_entry = {
+ .attr = {.name = "physical_block_size", .mode = S_IRUGO },
+ .show = queue_physical_block_size_show,
+};
+
+static struct queue_sysfs_entry queue_io_min_entry = {
+ .attr = {.name = "minimum_io_size", .mode = S_IRUGO },
+ .show = queue_io_min_show,
+};
+
+static struct queue_sysfs_entry queue_io_opt_entry = {
+ .attr = {.name = "optimal_io_size", .mode = S_IRUGO },
+ .show = queue_io_opt_show,
+};
+
static struct queue_sysfs_entry queue_nonrot_entry = {
.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
.show = queue_nonrot_show,
@@ -289,6 +319,9 @@ static struct attribute *default_attrs[] = {
&queue_iosched_entry.attr,
&queue_hw_sector_size_entry.attr,
&queue_logical_block_size_entry.attr,
+ &queue_physical_block_size_entry.attr,
+ &queue_io_min_entry.attr,
+ &queue_io_opt_entry.attr,
&queue_nonrot_entry.attr,
&queue_nomerges_entry.attr,
&queue_rq_affinity_entry.attr,
diff --git a/block/genhd.c b/block/genhd.c
index 1a4916e..fe7ccc0 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -852,11 +852,21 @@ static ssize_t disk_capability_show(struct device *dev,
return sprintf(buf, "%x\n", disk->flags);
}
+static ssize_t disk_alignment_offset_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct gendisk *disk = dev_to_disk(dev);
+
+ return sprintf(buf, "%d\n", queue_alignment_offset(disk->queue));
+}
+
static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
+static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
#ifdef CONFIG_FAIL_MAKE_REQUEST
@@ -875,6 +885,7 @@ static struct attribute *disk_attrs[] = {
&dev_attr_removable.attr,
&dev_attr_ro.attr,
&dev_attr_size.attr,
+ &dev_attr_alignment_offset.attr,
&dev_attr_capability.attr,
&dev_attr_stat.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 99e33ef..0af3608 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -219,6 +219,13 @@ ssize_t part_size_show(struct device *dev,
return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects);
}
+ssize_t part_alignment_offset_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct hd_struct *p = dev_to_part(dev);
+ return sprintf(buf, "%llu\n", (unsigned long long)p->alignment_offset);
+}
+
ssize_t part_stat_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -272,6 +279,7 @@ ssize_t part_fail_store(struct device *dev,
static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL);
static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
+static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
#ifdef CONFIG_FAIL_MAKE_REQUEST
static struct device_attribute dev_attr_fail =
@@ -282,6 +290,7 @@ static struct attribute *part_attrs[] = {
&dev_attr_partition.attr,
&dev_attr_start.attr,
&dev_attr_size.attr,
+ &dev_attr_alignment_offset.attr,
&dev_attr_stat.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&dev_attr_fail.attr,
@@ -383,6 +392,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
pdev = part_to_dev(p);
p->start_sect = start;
+ p->alignment_offset = queue_sector_alignment_offset(disk->queue, start);
p->nr_sects = len;
p->partno = partno;
p->policy = get_disk_ro(disk);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2655673..943a661 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -314,11 +314,16 @@ struct queue_limits {
unsigned int max_hw_sectors;
unsigned int max_sectors;
unsigned int max_segment_size;
+ unsigned int physical_block_size;
+ unsigned int alignment_offset;
+ unsigned int io_min;
+ unsigned int io_opt;
unsigned short logical_block_size;
unsigned short max_hw_segments;
unsigned short max_phys_segments;
+ unsigned char misaligned;
unsigned char no_cluster;
};
@@ -909,6 +914,15 @@ extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_physical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_alignment_offset(struct request_queue *q,
+ unsigned int alignment);
+extern void blk_queue_io_min(struct request_queue *q, unsigned int min);
+extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
+extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ sector_t offset);
+extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
+ sector_t offset);
extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
extern void blk_queue_dma_pad(struct request_queue *, unsigned int);
extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int);
@@ -1045,6 +1059,39 @@ static inline unsigned short bdev_logical_block_size(struct block_device *bdev)
return queue_logical_block_size(bdev_get_queue(bdev));
}
+static inline unsigned int queue_physical_block_size(struct request_queue *q)
+{
+ return q->limits.physical_block_size;
+}
+
+static inline unsigned int queue_io_min(struct request_queue *q)
+{
+ return q->limits.io_min;
+}
+
+static inline unsigned int queue_io_opt(struct request_queue *q)
+{
+ return q->limits.io_opt;
+}
+
+static inline int queue_alignment_offset(struct request_queue *q)
+{
+ if (q && q->limits.misaligned)
+ return -1;
+
+ if (q && q->limits.alignment_offset)
+ return q->limits.alignment_offset;
+
+ return 0;
+}
+
+static inline int queue_sector_alignment_offset(struct request_queue *q,
+ sector_t sector)
+{
+ return ((sector << 9) - q->limits.alignment_offset)
+ & (q->limits.io_min - 1);
+}
+
static inline int queue_dma_alignment(struct request_queue *q)
{
return q ? q->dma_alignment : 511;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index a1a28ca..149fda2 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -90,6 +90,7 @@ struct disk_stats {
struct hd_struct {
sector_t start_sect;
sector_t nr_sects;
+ sector_t alignment_offset;
struct device __dev;
struct kobject *holder_dir;
int policy, partno;
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-20 21:19 ` Martin K. Petersen
@ 2009-05-22 7:30 ` Jens Axboe
2009-05-22 13:34 ` Martin K. Petersen
0 siblings, 1 reply; 32+ messages in thread
From: Jens Axboe @ 2009-05-22 7:30 UTC (permalink / raw)
To: Martin K. Petersen; +Cc: linux-ide, linux-scsi
On Wed, May 20 2009, Martin K. Petersen wrote:
> >>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
>
> Jens> If you repost an updated 5/13 patch and I'll add it to the mix.
>
> block: Export I/O topology for block devices and partitions
>
> To support devices with physical block sizes bigger than 512 bytes we
> need to ensure proper alignment. This patch adds support for exposing
> I/O topology characteristics as devices are stacked.
>
> logical_block_size is the smallest unit the device can address.
>
> physical_block_size indicates the smallest I/O the device can write
> without incurring a read-modify-write penalty.
>
> The alignment_offset parameter indicates the number of bytes the start
> of the device/partition is offset from the device's natural alignment.
> Partition tools and MD/DM utilities can use this to pad their offsets
> so filesystems start on proper boundaries.
>
> The io_min parameter is the smallest preferred I/O size reported by
> the device. In many cases this is the same as the physical block
> size. However, the io_min parameter can be scaled up when stacking
> (RAID5 chunk size > physical block size).
>
> The io_opt characteristic indicates the optimal I/O size reported by
> the device. This is usually the stripe width for arrays.
>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
>
I replaced the original patch and went to apply this, but it fails even
at the first patch. What is this against? If you want it queued for
2.6.31, please post it against the for-2.6.31 branch of the block repo.
--
Jens Axboe
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-22 7:30 ` Jens Axboe
@ 2009-05-22 13:34 ` Martin K. Petersen
2009-05-22 18:16 ` Jens Axboe
0 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-05-22 13:34 UTC (permalink / raw)
To: Jens Axboe; +Cc: Martin K. Petersen, linux-ide, linux-scsi
>>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
Jens> I replaced the original patch and went to apply this, but it fails
Jens> even at the first patch. What is this against? If you want it
Jens> queued for 2.6.31, please post it against the for-2.6.31 branch of
Jens> the block repo.
Weird. It was cut against your for-2.6.31 branch as of a few days ago.
I just updated to your latest and greatest and the patches still apply
cleanly for me.
Are you sure you got the patch order right?
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 05/13] block: Export I/O topology for block devices and partitions
2009-05-22 13:34 ` Martin K. Petersen
@ 2009-05-22 18:16 ` Jens Axboe
0 siblings, 0 replies; 32+ messages in thread
From: Jens Axboe @ 2009-05-22 18:16 UTC (permalink / raw)
To: Martin K. Petersen; +Cc: linux-ide, linux-scsi
On Fri, May 22 2009, Martin K. Petersen wrote:
> >>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
>
> Jens> I replaced the original patch and went to apply this, but it fails
> Jens> even at the first patch. What is this against? If you want it
> Jens> queued for 2.6.31, please post it against the for-2.6.31 branch of
> Jens> the block repo.
>
> Weird. It was cut against your for-2.6.31 branch as of a few days ago.
> I just updated to your latest and greatest and the patches still apply
> cleanly for me.
That is weird...
> Are you sure you got the patch order right?
Using git am, it seems to pick them up in the right order:
axboe@carl:~/git/linux-2.6-block$ git am -s mkp
Applying: block: Do away with the notion of hardsect_size
Applying: block: Use accessor functions for queue limits
error: patch failed: block/blk-map.c:291
error: block/blk-map.c: patch does not apply
Patch failed at 0002 block: Use accessor functions for queue limits
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
My for-2.6.31 branch is at b9ed7252d219c1c663944bf03846eabb515dbe75
--
Jens Axboe
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 02/13] block: Use accessor functions for queue limits
2009-05-15 4:40 ` [PATCH 02/13] block: Use accessor functions for queue limits Martin K. Petersen
@ 2009-05-31 15:51 ` Bartlomiej Zolnierkiewicz
2009-06-01 5:08 ` Martin K. Petersen
0 siblings, 1 reply; 32+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-05-31 15:51 UTC (permalink / raw)
To: Martin K. Petersen
Cc: rwheeler, snitzer, jeff, neilb, James.Bottomley, jens.axboe,
linux-ide, linux-scsi
Hi Martin,
On Friday 15 May 2009 06:40:24 Martin K. Petersen wrote:
> From: Martin K. Petersen <martin.petersen@oracle.com>
>
> Convert all external users of queue limits to using wrapper functions
> instead of poking the request queue variables directly.
>
> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
> --- a/drivers/md/dm-table.c
> +++ b/drivers/md/dm-table.c
[...]
> @@ -914,13 +914,13 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
> * restrictions.
> */
> blk_queue_max_sectors(q, t->limits.max_sectors);
> - q->max_phys_segments = t->limits.max_phys_segments;
> - q->max_hw_segments = t->limits.max_hw_segments;
> - q->logical_block_size = t->limits.logical_block_size;
> - q->max_segment_size = t->limits.max_segment_size;
> - q->max_hw_sectors = t->limits.max_hw_sectors;
> - q->seg_boundary_mask = t->limits.seg_boundary_mask;
> - q->bounce_pfn = t->limits.bounce_pfn;
> + blk_queue_max_phys_segments(q, t->limits.max_phys_segments);
> + blk_queue_max_hw_segments(q, t->limits.max_hw_segments);
> + blk_queue_logical_block_size(q, t->limits.logical_block_size);
> + blk_queue_max_segment_size(q, t->limits.max_segment_size);
> + blk_queue_max_hw_sectors(q, t->limits.max_hw_sectors);
> + blk_queue_segment_boundary(q, t->limits.seg_boundary_mask);
> + blk_queue_bounce_limit(q, t->limits.bounce_pfn);
This chunk triggers a following warning on one of my systems:
BUG: sleeping function called from invalid context at mm/page_alloc.c:1482
in_atomic(): 1, irqs_disabled(): 0, pid: 3584, name: cryptsetup
2 locks held by cryptsetup/3584:
#0: (&md->suspend_lock){+.+.+.}, at: [<c0307810>] dm_swap_table+0x21/0x132
#1: (&md->map_lock){+++++.}, at: [<c03078ef>] dm_swap_table+0x100/0x132
Pid: 3584, comm: cryptsetup Not tainted 2.6.30-rc7-next-20090529-06589-g7701864-dirty #8
Call Trace:
[<c0145d06>] ? __debug_show_held_locks+0x1e/0x20
[<c012182a>] __might_sleep+0xfb/0x102
[<c0161bac>] __alloc_pages_internal+0x62/0x388
[<c015ea59>] mempool_alloc_pages+0x1b/0x21
[<c0175997>] mempool_alloc_pages_isa+0xb/0x10
[<c015ee59>] mempool_create_node+0x92/0xcc
[<c015ea34>] ? mempool_free_pages+0x0/0xa
[<c017598c>] ? mempool_alloc_pages_isa+0x0/0x10
[<c015eea0>] mempool_create+0xd/0x11
[<c017596c>] init_emergency_isa_pool+0x22/0x42
[<c0221e26>] blk_queue_bounce_limit+0x2c/0x41
[<c0309813>] dm_table_set_restrictions+0x76/0x9b
[<c0307906>] dm_swap_table+0x117/0x132
[<c030be21>] dev_suspend+0xef/0x15a
[<c030c66d>] dm_ctl_ioctl+0x18e/0x1cd
[<c030bd32>] ? dev_suspend+0x0/0x15a
[<c030c4df>] ? dm_ctl_ioctl+0x0/0x1cd
[<c018a433>] vfs_ioctl+0x22/0x69
[<c018a8fd>] do_vfs_ioctl+0x483/0x4bd
[<c01921da>] ? mntput_no_expire+0x19/0xb4
[<c0180b0a>] ? __fput+0x185/0x18d
[<c01029fb>] ? sysenter_exit+0xf/0x18
[<c018a963>] sys_ioctl+0x2c/0x45
[<c01029c8>] sysenter_do_call+0x12/0x36
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 02/13] block: Use accessor functions for queue limits
2009-05-31 15:51 ` Bartlomiej Zolnierkiewicz
@ 2009-06-01 5:08 ` Martin K. Petersen
2009-06-01 5:15 ` Jens Axboe
0 siblings, 1 reply; 32+ messages in thread
From: Martin K. Petersen @ 2009-06-01 5:08 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz
Cc: Martin K. Petersen, rwheeler, snitzer, jeff, neilb,
James.Bottomley, jens.axboe, linux-ide, linux-scsi
>>>>> "Bart" == Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> writes:
>> Convert all external users of queue limits to using wrapper functions
>> instead of poking the request queue variables directly.
Did bisect this?
The patch you mention didn't touch the bounce limits at all. One of my
other patches moved portions of the queue limits to an embedded struct.
However, it was purely variable renaming. I have not touched anything
related to memory allocations.
[...]
Bart> init_emergency_isa_pool+0x22/0x42 [<c0221e26>]
Bart> blk_queue_bounce_limit+0x2c/0x41 [<c0309813>]
[...]
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 02/13] block: Use accessor functions for queue limits
2009-06-01 5:08 ` Martin K. Petersen
@ 2009-06-01 5:15 ` Jens Axboe
2009-06-01 5:28 ` Martin K. Petersen
0 siblings, 1 reply; 32+ messages in thread
From: Jens Axboe @ 2009-06-01 5:15 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Bartlomiej Zolnierkiewicz, rwheeler, snitzer, jeff, neilb,
James.Bottomley, linux-ide, linux-scsi
On Mon, Jun 01 2009, Martin K. Petersen wrote:
> >>>>> "Bart" == Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> writes:
>
> >> Convert all external users of queue limits to using wrapper functions
> >> instead of poking the request queue variables directly.
>
> Did bisect this?
>
> The patch you mention didn't touch the bounce limits at all. One of my
> other patches moved portions of the queue limits to an embedded struct.
> However, it was purely variable renaming. I have not touched anything
> related to memory allocations.
It replaces
q->bounce_pfn = t->limits.bounce_pfn;
with
blk_queue_bounce_limit(q, t->limits.bounce_pfn);
which are definitely not a functionally equivalent change.
--
Jens Axboe
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 02/13] block: Use accessor functions for queue limits
2009-06-01 5:15 ` Jens Axboe
@ 2009-06-01 5:28 ` Martin K. Petersen
0 siblings, 0 replies; 32+ messages in thread
From: Martin K. Petersen @ 2009-06-01 5:28 UTC (permalink / raw)
To: Jens Axboe
Cc: Martin K. Petersen, Bartlomiej Zolnierkiewicz, rwheeler, snitzer,
jeff, neilb, James.Bottomley, linux-ide, linux-scsi
>>>>> "Jens" == Jens Axboe <jens.axboe@oracle.com> writes:
Jens> It replaces
Jens> q-> bounce_pfn = t->limits.bounce_pfn;
Jens> with
Jens> blk_queue_bounce_limit(q, t->limits.bounce_pfn);
Jens> which are definitely not a functionally equivalent change.
Ah, now I see it. Yeah, that's a bug. I must have thought
blk_queue_bounce_limit() was one of my wrapper functions when I made
that change. It follows the same naming scheme.
Will fix.
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2009-06-01 5:30 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-15 4:40 I/O Topology v3 Martin K. Petersen
2009-05-15 4:40 ` [PATCH 01/13] block: Do away with the notion of hardsect_size Martin K. Petersen
2009-05-15 4:40 ` [PATCH 02/13] block: Use accessor functions for queue limits Martin K. Petersen
2009-05-31 15:51 ` Bartlomiej Zolnierkiewicz
2009-06-01 5:08 ` Martin K. Petersen
2009-06-01 5:15 ` Jens Axboe
2009-06-01 5:28 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 03/13] block: Move queue limits to an embedded struct Martin K. Petersen
2009-05-18 18:50 ` Mike Snitzer
2009-05-18 18:52 ` Mike Snitzer
2009-05-19 16:46 ` Martin K. Petersen
2009-05-15 4:40 ` [PATCH 04/13] block: Expose stacked device queues in sysfs Martin K. Petersen
2009-05-15 4:40 ` [PATCH 05/13] block: Export I/O topology for block devices and partitions Martin K. Petersen
2009-05-18 17:57 ` Jens Axboe
2009-05-18 18:12 ` Mike Snitzer
2009-05-19 16:41 ` Martin K. Petersen
2009-05-19 18:15 ` Jens Axboe
2009-05-20 21:19 ` Martin K. Petersen
2009-05-22 7:30 ` Jens Axboe
2009-05-22 13:34 ` Martin K. Petersen
2009-05-22 18:16 ` Jens Axboe
2009-05-15 4:40 ` [PATCH 06/13] MD: Use new topology calls to indicate alignment and I/O sizes Martin K. Petersen
2009-05-15 4:40 ` [PATCH 07/13] block: Deprecate blk_queue_stack_limits Martin K. Petersen
2009-05-15 4:40 ` [PATCH 08/13] sd: Physical block size and alignment support Martin K. Petersen
2009-05-15 4:40 ` [PATCH 09/13] sd: Detect non-rotational devices Martin K. Petersen
2009-05-15 4:40 ` [PATCH 10/13] sd: Block limits VPD support Martin K. Petersen
2009-05-15 4:40 ` [PATCH 11/13] scsi_debug: Add support for physical block exponent and alignment Martin K. Petersen
2009-05-19 15:11 ` Douglas Gilbert
2009-05-15 4:40 ` [PATCH 12/13] libata: Report disk alignment and physical block size Martin K. Petersen
2009-05-15 18:17 ` Jeff Garzik
2009-05-15 4:40 ` [PATCH 13/13] libata: Media rotation rate and form factor heuristics Martin K. Petersen
2009-05-15 18:17 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).