diff options
author | Chunwei Chen <[email protected]> | 2015-07-30 22:24:36 +0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-08-24 10:17:06 -0700 |
commit | 5475aada9474464f973788c1b2fc6216486fb303 (patch) | |
tree | f4b02aff6e841b47cad4894b40c7a1092ad0be3b /module/zfs/dmu.c | |
parent | 17888ae30d6111f1fe25087a256724ee9b1a0a84 (diff) |
Linux 4.1 compat: loop device on ZFS
Starting from Linux 4.1 allows iov_iter with bio_vec to be passed into
iter_read/iter_write. Notably, the loop device will pass bio_vec to backend
filesystem. However, current ZFS code assumes iovec without any check, so it
will always crash when using loop device.
With the restructured uio_t, we can safely pass bio_vec in uio_t with UIO_BVEC
set. The uio* functions are modified to handle bio_vec case separately.
The const uio_iov causes some warning in xuio related stuff, so explicit
convert them to non const.
Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Richard Yao <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3511
Closes #3640
Diffstat (limited to 'module/zfs/dmu.c')
-rw-r--r-- | module/zfs/dmu.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index eb3bc0ed2..ac7499d01 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -23,6 +23,7 @@ * Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2015 by Chunwei Chen. All rights reserved. */ #include <sys/dmu.h> @@ -933,7 +934,7 @@ dmu_xuio_init(xuio_t *xuio, int nblk) priv = kmem_zalloc(sizeof (dmu_xuio_t), KM_SLEEP); priv->cnt = nblk; priv->bufs = kmem_zalloc(nblk * sizeof (arc_buf_t *), KM_SLEEP); - priv->iovp = uio->uio_iov; + priv->iovp = (iovec_t *)uio->uio_iov; XUIO_XUZC_PRIV(xuio) = priv; if (XUIO_XUZC_RW(xuio) == UIO_READ) @@ -974,7 +975,7 @@ dmu_xuio_add(xuio_t *xuio, arc_buf_t *abuf, offset_t off, size_t n) ASSERT(i < priv->cnt); ASSERT(off + n <= arc_buf_size(abuf)); - iov = uio->uio_iov + i; + iov = (iovec_t *)uio->uio_iov + i; iov->iov_base = (char *)abuf->b_data + off; iov->iov_len = n; priv->bufs[i] = abuf; |