summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zio.c
diff options
context:
space:
mode:
authorAlex Reece <alex@delphix.com>2014-07-16 12:09:51 -0800
committerChristopher Siden <chris@delphix.com>2014-07-16 13:09:51 -0700
commit2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55 (patch)
tree077b2ce0ae3e4da2c3dde0f5760089db1994d897 /usr/src/uts/common/fs/zfs/zio.c
parentb4ecf764d8099c92d5c9c0f13a45514377f3d292 (diff)
downloadillumos-joyent-2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55.tar.gz
4958 zdb trips assert on pools with ashift >= 0xe
Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Max Grossman <max.grossman@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zio.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zio.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c
index e60f0eb614..d8833f6707 100644
--- a/usr/src/uts/common/fs/zfs/zio.c
+++ b/usr/src/uts/common/fs/zfs/zio.c
@@ -815,8 +815,8 @@ zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
ASSERT3U(offset + size, <=, vd->vdev_psize);
zio = zio_create(pio, vd->vdev_spa, 0, NULL, data, size, done, private,
- ZIO_TYPE_READ, priority, flags, vd, offset, NULL,
- ZIO_STAGE_OPEN, ZIO_READ_PHYS_PIPELINE);
+ ZIO_TYPE_READ, priority, flags | ZIO_FLAG_PHYSICAL, vd, offset,
+ NULL, ZIO_STAGE_OPEN, ZIO_READ_PHYS_PIPELINE);
zio->io_prop.zp_checksum = checksum;
@@ -836,8 +836,8 @@ zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
ASSERT3U(offset + size, <=, vd->vdev_psize);
zio = zio_create(pio, vd->vdev_spa, 0, NULL, data, size, done, private,
- ZIO_TYPE_WRITE, priority, flags, vd, offset, NULL,
- ZIO_STAGE_OPEN, ZIO_WRITE_PHYS_PIPELINE);
+ ZIO_TYPE_WRITE, priority, flags | ZIO_FLAG_PHYSICAL, vd, offset,
+ NULL, ZIO_STAGE_OPEN, ZIO_WRITE_PHYS_PIPELINE);
zio->io_prop.zp_checksum = checksum;
@@ -2508,7 +2508,9 @@ zio_vdev_io_start(zio_t *zio)
align = 1ULL << vd->vdev_top->vdev_ashift;
- if (P2PHASE(zio->io_size, align) != 0) {
+ if (!(zio->io_flags & ZIO_FLAG_PHYSICAL) &&
+ P2PHASE(zio->io_size, align) != 0) {
+ /* Transform logical writes to be a full physical block size. */
uint64_t asize = P2ROUNDUP(zio->io_size, align);
char *abuf = zio_buf_alloc(asize);
ASSERT(vd == vd->vdev_top);
@@ -2519,8 +2521,22 @@ zio_vdev_io_start(zio_t *zio)
zio_push_transform(zio, abuf, asize, asize, zio_subblock);
}
- ASSERT(P2PHASE(zio->io_offset, align) == 0);
- ASSERT(P2PHASE(zio->io_size, align) == 0);
+ /*
+ * If this is not a physical io, make sure that it is properly aligned
+ * before proceeding.
+ */
+ if (!(zio->io_flags & ZIO_FLAG_PHYSICAL)) {
+ ASSERT0(P2PHASE(zio->io_offset, align));
+ ASSERT0(P2PHASE(zio->io_size, align));
+ } else {
+ /*
+ * For physical writes, we allow 512b aligned writes and assume
+ * the device will perform a read-modify-write as necessary.
+ */
+ ASSERT0(P2PHASE(zio->io_offset, SPA_MINBLOCKSIZE));
+ ASSERT0(P2PHASE(zio->io_size, SPA_MINBLOCKSIZE));
+ }
+
VERIFY(zio->io_type != ZIO_TYPE_WRITE || spa_writeable(spa));
/*