From a41306fbc788d2d58b0b92fb416056a922af925d Mon Sep 17 00:00:00 2001 From: Haakan Johansson Date: Fri, 16 Sep 2016 10:25:01 +0200 Subject: [PATCH] Keep track of mixed nonrotary (ssd+hdd) devices. --- include/sys/vdev_impl.h | 2 ++ module/zfs/vdev.c | 10 +++++++++- module/zfs/vdev_disk.c | 2 ++ module/zfs/vdev_file.c | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h index 0d09c81c7f83..4898a5c6502b 100644 --- a/include/sys/vdev_impl.h +++ b/include/sys/vdev_impl.h @@ -154,6 +154,8 @@ struct vdev { boolean_t vdev_expanding; /* expand the vdev? */ boolean_t vdev_reopening; /* reopen in progress? */ boolean_t vdev_nonrot; /* true if solid state */ + boolean_t vdev_nonrot_some; /* true if at least one solid state */ + boolean_t vdev_nonrot_mix; /* true if partial solid state */ int vdev_open_error; /* error on last open */ kthread_t *vdev_open_thread; /* thread opening children */ uint64_t vdev_crtxg; /* txg when top-level was added */ diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index dcf56d8df741..8bfd8df239b6 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -1125,6 +1125,9 @@ vdev_open_child(void *arg) vd->vdev_open_error = vdev_open(vd); vd->vdev_open_thread = NULL; vd->vdev_parent->vdev_nonrot &= vd->vdev_nonrot; + vd->vdev_parent->vdev_nonrot_some |= vd->vdev_nonrot; + vd->vdev_parent->vdev_nonrot_mix = + vd->vdev_parent->vdev_nonrot ^ vd->vdev_parent->vdev_nonrot_some; } static boolean_t @@ -1163,7 +1166,9 @@ vdev_open_children(vdev_t *vd) vd->vdev_child[c]->vdev_open_error = vdev_open(vd->vdev_child[c]); vd->vdev_nonrot &= vd->vdev_child[c]->vdev_nonrot; + vd->vdev_nonrot_some |= vd->vdev_child[c]->vdev_nonrot; } + vd->vdev_nonrot_mix = vd->vdev_nonrot ^ vd->vdev_nonrot_some; return; } tq = taskq_create("vdev_open", children, minclsyspri, @@ -1175,8 +1180,11 @@ vdev_open_children(vdev_t *vd) taskq_destroy(tq); - for (c = 0; c < children; c++) + for (c = 0; c < children; c++) { vd->vdev_nonrot &= vd->vdev_child[c]->vdev_nonrot; + vd->vdev_nonrot_some |= vd->vdev_child[c]->vdev_nonrot; + } + vd->vdev_nonrot_mix = vd->vdev_nonrot ^ vd->vdev_nonrot_some; } /* diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index e399e6630639..8c14ab0c6ad5 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -320,6 +320,8 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, /* Inform the ZIO pipeline that we are non-rotational */ v->vdev_nonrot = blk_queue_nonrot(bdev_get_queue(vd->vd_bdev)); + v->vdev_nonrot_some = v->vdev_nonrot; + v->vdev_nonrot_mix = B_FALSE; /* Physical volume size in bytes */ *psize = bdev_capacity(vd->vd_bdev); diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c index bca4175a6ff4..61239697bc1e 100644 --- a/module/zfs/vdev_file.c +++ b/module/zfs/vdev_file.c @@ -59,6 +59,8 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, /* Rotational optimizations only make sense on block devices */ vd->vdev_nonrot = B_TRUE; + vd->vdev_nonrot_some = vd->vdev_nonrot; + vd->vdev_nonrot_mix = B_FALSE; /* * We must have a pathname, and it must be absolute.