On 5/7/14, 10:55 AM, Steven Hartland wrote:
----- Original Message ----- From: "George Wilson"
<george.wil...@delphix.com>
To: "Steven Hartland" <kill...@multiplay.co.uk>; <developer@open-zfs.org>
Sent: Wednesday, May 07, 2014 3:07 PM
Subject: Re: [OpenZFS Developer] zfs zio reordering in
zio_vdev_io_start causing panics
On 5/7/14, 4:44 AM, Steven Hartland wrote:
----- Original Message ----- From: "George Wilson"
I think there is probably another way we can solve this problem but
I first want to get a better understanding of the corruption. We
have not integrated the TRIM support upstream and I suspect that's
the source of most of the problems. Can you confirm that with TRIM
disabled that most of corruption you've seen does not occur? I'm
trying to get context here since we've not seen this type of
failure elsewhere.
In the case of TRIM if BIO delete's are disabled the free IO's don't
get
sent to physical media and instead instantly return
ZIO_PIPELINE_CONTINUE.
static int
vdev_geom_io_start(zio_t *zio)
{
...
switch (zio->io_type) {
case ZIO_TYPE_FREE:
if (vdev_geom_bio_delete_disable)
return (ZIO_PIPELINE_CONTINUE);
}
}
For your simple corruption case could you change the code to do the
following:
if (vdev_geom_bio_delete_disable) {
zio_interrupt(zio);
return (ZIO_PIPELINE_STOP);
}
I believe this is the way it should behave. Let me know how this work
for you. I'm going to change the way the lower consumer work and do
some testing also.
So your saying no path from vdev_*io_start(..) that queues an IO return
ZIO_PIPELINE_CONTINUE?
If so it looks like there's a number of locations where that needs fixing
at least in head of FreeBSD e.g.
static int
vdev_file_io_start(zio_t *zio)
{
...
if (!vdev_readable(vd)) {
zio->io_error = SET_ERROR(ENXIO);
return (ZIO_PIPELINE_CONTINUE);
}
-----
static int
vdev_mirror_io_start(zio_t *zio)
{
...
if (zio->io_type == ZIO_TYPE_READ) {
if ((zio->io_flags & ZIO_FLAG_SCRUB) && !mm->mm_replacing) {
...
return (ZIO_PIPELINE_CONTINUE);
}
...
return (ZIO_PIPELINE_CONTINUE);
}
----
Also should that be asserted to make it clear and testable e.g.
static int
zio_vdev_io_start(zio_t *zio)
{
zio_t *sio = zio;
...
ret = vd->vdev_ops->vdev_op_io_start(zio);
ASSERT(ret != ZIO_PIPELINE_CONTINUE || sio == zio);
return (ret);
}
This would also ensure the stack overflow issue shouldn't occur.
Regards
Steve
There are a couple of cases where it can work but I'm going to make it
such that requires you to always return back ZIO_PIPELINE_STOP.
Otherwise it's makes it too easy to introduce a programming error. For
example, vdev_mirror_io_start() could return ZIO_PIPELINE_CONTINUE but
vdev_disk_io_start() shouldn't.
I'll try to have a diff ready soon. I will be interested in your test
results.
- George
_______________________________________________
developer mailing list
developer@open-zfs.org
http://lists.open-zfs.org/mailman/listinfo/developer