aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dmu.c
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2015-07-30 22:24:36 +0800
committerBrian Behlendorf <[email protected]>2015-08-24 10:17:06 -0700
commit5475aada9474464f973788c1b2fc6216486fb303 (patch)
treef4b02aff6e841b47cad4894b40c7a1092ad0be3b /module/zfs/dmu.c
parent17888ae30d6111f1fe25087a256724ee9b1a0a84 (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.c5
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;