aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_vnops.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/zfs_vnops.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/zfs_vnops.c')
-rw-r--r--module/zfs/zfs_vnops.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index 1d23d6db3..5e5f3c8db 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
*/
/* Portions Copyright 2007 Jeremy Teo */
@@ -591,10 +592,10 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
int max_blksz = zsb->z_max_blksz;
int error = 0;
arc_buf_t *abuf;
- iovec_t *aiov = NULL;
+ const iovec_t *aiov = NULL;
xuio_t *xuio = NULL;
int i_iov = 0;
- iovec_t *iovp = uio->uio_iov;
+ const iovec_t *iovp = uio->uio_iov;
int write_eof;
int count = 0;
sa_bulk_attr_t bulk[4];
@@ -714,6 +715,7 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
if (xuio && abuf == NULL) {
ASSERT(i_iov < iovcnt);
+ ASSERT3U(uio->uio_segflg, !=, UIO_BVEC);
aiov = &iovp[i_iov];
abuf = dmu_xuio_arcbuf(xuio, i_iov);
dmu_xuio_clear(xuio, i_iov);