+ /* Allow concurrent I/O only for disks */
+ isdisk = cdev_type(dev) == D_DISK;
+ if (!isdisk)
+ concurrency = 0;
+
/* Make sure we have a buffer, creating one if necessary. */
if (obp != NULL) {
mutex_enter(&bufcache_lock);
@@ -291,11 +302,30 @@ physio(void (*strategy)(struct buf *), s
/* Set up the buffer for a maximum-sized transfer. */
bp->b_blkno = btodb(uio->uio_offset);
- if (dbtob(bp->b_blkno) != uio->uio_offset) {
- error = EINVAL;
- goto done;
+ if (isdisk) {
+ /*
+ * For disks, check that offsets are at least block
+ * aligned, the block addresses are used to track
+ * errors of finished requests.
+ */
+ if (dbtob(bp->b_blkno) != uio->uio_offset) {
+ error = EINVAL;
+ goto done;
+ }
+ /*
+ * Split request into MAXPHYS chunks
+ */
+ bp->b_bcount = MIN(MAXPHYS, iovp->iov_len);
+ } else {
+ /*
+ * Verify that buffer can handle size
+ */
+ if (iovp->iov_len > MAXBSIZE) {
+ error = EINVAL;
+ goto done;
+ }
+ bp->b_bcount = iovp->iov_len;
}
- bp->b_bcount = MIN(MAXPHYS, iovp->iov_len);
bp->b_data = iovp->iov_base;