From 4ed0e1d18dd421f399e128dff00c9861fb1d5707 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Tue, 31 Jan 2017 12:34:08 -0800 Subject: [PATCH] vds: Add physical block support Version 1.2 of the virtual IO device protocol added physical block support. Start sending the underlaying physical block device size. Signed-off-by: Liam R. Howlett Reviewed-by: Shannon Nelson Reviewed-by: Rob Gardner Orabug: 19420123 Signed-off-by: Allen Pais --- drivers/block/vds/vds.h | 1 + drivers/block/vds/vds_blk.c | 4 ++-- drivers/block/vds/vds_io.c | 15 +++++++++++++-- drivers/block/vds/vds_io.h | 2 ++ drivers/block/vds/vds_main.c | 5 +++-- drivers/block/vds/vds_reg.c | 19 ++++++++++++++++--- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/block/vds/vds.h b/drivers/block/vds/vds.h index 32474291508f..362c78ca3535 100644 --- a/drivers/block/vds/vds.h +++ b/drivers/block/vds/vds.h @@ -42,6 +42,7 @@ struct vds_port { u64 max_xfer_size; u64 vdisk_size; u32 vdisk_bsize; + u32 vdisk_phy_bsize; u32 msglen; u64 seq; const char *path; diff --git a/drivers/block/vds/vds_blk.c b/drivers/block/vds/vds_blk.c index 38c762c5a1c4..9cc1635f3dee 100644 --- a/drivers/block/vds/vds_blk.c +++ b/drivers/block/vds/vds_blk.c @@ -19,8 +19,8 @@ static int vds_blk_init(struct vds_port *port) port->vdisk_bsize = bdev_logical_block_size(bdev); port->vdisk_size = i_size_read(bdev->bd_inode) / port->vdisk_bsize; - port->max_xfer_size = to_bytes(blk_queue_get_max_sectors( - bdev_get_queue(bdev), 0)) / port->vdisk_bsize; + port->max_xfer_size = vds_io_max_xfer_size(port, bdev); + port->vdisk_phy_bsize = bdev_physical_block_size(bdev); port->be_data = bdev; diff --git a/drivers/block/vds/vds_io.c b/drivers/block/vds/vds_io.c index f8473ad0d797..1315cb5fb6cd 100644 --- a/drivers/block/vds/vds_io.c +++ b/drivers/block/vds/vds_io.c @@ -689,8 +689,9 @@ int vds_be_init(struct vds_port *port) udelay(VDS_DEV_DELAY); } - vdsdbg(HS, "vdisk_blk_sz=%u vdisk_sz=%llu max_xfer_sz=%llu\n", - port->vdisk_bsize, port->vdisk_size, port->max_xfer_size); + vdsdbg(HS, "vdisk_blk_sz=%u vdisk_sz=%llu vdisk_phy_blk_sz=%u max_xfer_sz=%llu\n", + port->vdisk_bsize, port->vdisk_size, port->vdisk_phy_bsize, + port->max_xfer_size); if (!(port->vdisk_bsize && port->vdisk_size && port->max_xfer_size)) { rv = -EINVAL; @@ -747,3 +748,13 @@ void vds_be_fini(struct vds_port *port) } vds_be_wunlock(port); } + +int vds_io_max_xfer_size(struct vds_port *port, struct block_device *bdev) +{ + unsigned max_sect = blk_queue_get_max_sectors(bdev_get_queue(bdev), 0); + + if (max_sect == 0) + return 0; + + return to_bytes(max_sect) / port->vdisk_bsize; +} diff --git a/drivers/block/vds/vds_io.h b/drivers/block/vds/vds_io.h index 478929739307..643eb6f4556a 100644 --- a/drivers/block/vds/vds_io.h +++ b/drivers/block/vds/vds_io.h @@ -53,6 +53,8 @@ void vds_io_enq(struct vds_io *io); void vds_io_wait(struct vds_io *io); void vds_io_done(struct vds_io *io); +int vds_io_max_xfer_size(struct vds_port *port, struct block_device *bdev); + void *vds_get(struct vds_port *port, sector_t offset, u64 size); int vds_clear(struct vds_port *port, sector_t offset, u64 size); int vds_read(struct vds_port *port, void *addr, sector_t offset, u64 size); diff --git a/drivers/block/vds/vds_main.c b/drivers/block/vds/vds_main.c index d0655da88b35..9119864d20a5 100644 --- a/drivers/block/vds/vds_main.c +++ b/drivers/block/vds/vds_main.c @@ -181,6 +181,7 @@ static int vds_handle_attr(struct vio_driver_state *vio, void *arg) port->xfer_mode = pkt->xfer_mode; pkt->vdisk_block_size = port->vdisk_bsize; + pkt->phys_block_size = port->vdisk_phy_bsize; /* XXX OBP doesn't seem to honor max_xfer_size */ pkt->max_xfer_size = port->max_xfer_size; @@ -191,9 +192,9 @@ static int vds_handle_attr(struct vio_driver_state *vio, void *arg) pkt->tag.stype = VIO_SUBTYPE_ACK; pkt->tag.sid = vio_send_sid(vio); - vdsdbg(HS, "SEND ATTR dksz[%llu] blksz[%u] max_xfer[%llu] ops[%llx]\n", + vdsdbg(HS, "SEND ATTR dksz[%llu] blksz[%u] max_xfer[%llu] ops[%llx] physz[%u]\n", pkt->vdisk_size, pkt->vdisk_block_size, - pkt->max_xfer_size, pkt->operations); + pkt->max_xfer_size, pkt->operations, pkt->phys_block_size); return vio_ldc_send(vio, pkt, sizeof(*pkt)); } diff --git a/drivers/block/vds/vds_reg.c b/drivers/block/vds/vds_reg.c index cf7c157ff52c..fd8e94fd2ea4 100644 --- a/drivers/block/vds/vds_reg.c +++ b/drivers/block/vds/vds_reg.c @@ -7,18 +7,31 @@ #include "vds.h" #include "vds_io.h" +/* Default logical and physical block size */ +#define VDS_DEFAULT_BLK_SIZE 512 + static int vds_reg_init(struct vds_port *port) { struct file *file; + struct block_device *bdev; file = filp_open(port->path, O_RDWR | O_EXCL | O_LARGEFILE, 0); if (IS_ERR(file)) return (int)PTR_ERR(file); - port->vdisk_bsize = 512; + bdev = file->f_inode->i_sb->s_bdev; + if (bdev) { + port->vdisk_bsize = bdev_logical_block_size(bdev); + port->vdisk_phy_bsize = bdev_physical_block_size(bdev); + port->max_xfer_size = vds_io_max_xfer_size(port, bdev); + } else { + port->vdisk_bsize = VDS_DEFAULT_BLK_SIZE; + port->vdisk_phy_bsize = VDS_DEFAULT_BLK_SIZE; + port->max_xfer_size = 1024; + } + port->vdisk_size = i_size_read(file_inode(file)) / - port->vdisk_bsize; - port->max_xfer_size = 1024; + port->vdisk_bsize; port->be_data = file; -- 2.50.1