u64 max_xfer_size;
u64 vdisk_size;
u32 vdisk_bsize;
+ u32 vdisk_phy_bsize;
u32 msglen;
u64 seq;
const char *path;
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;
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;
}
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;
+}
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);
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;
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));
}
#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;