]>
Commit | Line | Data |
---|---|---|
4b393c50 | 1 | /* |
716154c5 BB |
2 | * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. |
3 | * Copyright (C) 2007 The Regents of the University of California. | |
ae89cf0f | 4 | * Copyright (c) 2015 by Chunwei Chen. All rights reserved. |
716154c5 BB |
5 | * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). |
6 | * Written by Brian Behlendorf <behlendorf1@llnl.gov>. | |
7 | * UCRL-CODE-235197 | |
8 | * | |
9 | * This file is part of the SPL, Solaris Porting Layer. | |
716154c5 BB |
10 | * |
11 | * The SPL is free software; you can redistribute it and/or modify it | |
12 | * under the terms of the GNU General Public License as published by the | |
13 | * Free Software Foundation; either version 2 of the License, or (at your | |
14 | * option) any later version. | |
15 | * | |
16 | * The SPL is distributed in the hope that it will be useful, but WITHOUT | |
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
19 | * for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License along | |
22 | * with the SPL. If not, see <http://www.gnu.org/licenses/>. | |
4b393c50 | 23 | */ |
716154c5 | 24 | |
6adf99e7 | 25 | #ifndef _SPL_UIO_H |
5461eefe | 26 | #define _SPL_UIO_H |
6adf99e7 | 27 | |
d6f67df6 | 28 | #include <sys/debug.h> |
73e540a0 | 29 | #include <linux/uio.h> |
ae89cf0f | 30 | #include <linux/blkdev.h> |
d6f67df6 MM |
31 | #include <linux/blkdev_compat.h> |
32 | #include <linux/mm.h> | |
33 | #include <linux/bio.h> | |
73e540a0 BB |
34 | #include <asm/uaccess.h> |
35 | #include <sys/types.h> | |
36 | ||
299fbf75 RE |
37 | #if defined(HAVE_VFS_IOV_ITER) && defined(HAVE_FAULT_IN_IOV_ITER_READABLE) |
38 | #define iov_iter_fault_in_readable(a, b) fault_in_iov_iter_readable(a, b) | |
39 | #endif | |
40 | ||
bb1bb2c4 BB |
41 | typedef struct iovec iovec_t; |
42 | ||
d0cd9a5c | 43 | typedef enum zfs_uio_rw { |
5461eefe BB |
44 | UIO_READ = 0, |
45 | UIO_WRITE = 1, | |
d0cd9a5c | 46 | } zfs_uio_rw_t; |
6adf99e7 | 47 | |
d0cd9a5c | 48 | typedef enum zfs_uio_seg { |
5461eefe BB |
49 | UIO_USERSPACE = 0, |
50 | UIO_SYSSPACE = 1, | |
1c2358c1 BB |
51 | UIO_BVEC = 2, |
52 | #if defined(HAVE_VFS_IOV_ITER) | |
53 | UIO_ITER = 3, | |
54 | #endif | |
d0cd9a5c | 55 | } zfs_uio_seg_t; |
73e540a0 | 56 | |
d0cd9a5c | 57 | typedef struct zfs_uio { |
ae89cf0f CC |
58 | union { |
59 | const struct iovec *uio_iov; | |
60 | const struct bio_vec *uio_bvec; | |
1c2358c1 BB |
61 | #if defined(HAVE_VFS_IOV_ITER) |
62 | struct iov_iter *uio_iter; | |
63 | #endif | |
ae89cf0f | 64 | }; |
bb1bb2c4 BB |
65 | int uio_iovcnt; |
66 | offset_t uio_loffset; | |
d0cd9a5c | 67 | zfs_uio_seg_t uio_segflg; |
779a6c0b | 68 | boolean_t uio_fault_disable; |
bb1bb2c4 BB |
69 | uint16_t uio_fmode; |
70 | uint16_t uio_extflg; | |
bb1bb2c4 | 71 | ssize_t uio_resid; |
6f73d021 | 72 | |
ae89cf0f | 73 | size_t uio_skip; |
6f73d021 TH |
74 | |
75 | struct request *rq; | |
76 | ||
77 | /* | |
78 | * Used for saving rq_for_each_segment() state between calls | |
79 | * to zfs_uiomove_bvec_rq(). | |
80 | */ | |
81 | struct req_iterator iter; | |
82 | struct bio_vec bv; | |
d0cd9a5c BA |
83 | } zfs_uio_t; |
84 | ||
6f73d021 | 85 | |
d0cd9a5c BA |
86 | #define zfs_uio_segflg(u) (u)->uio_segflg |
87 | #define zfs_uio_offset(u) (u)->uio_loffset | |
88 | #define zfs_uio_resid(u) (u)->uio_resid | |
89 | #define zfs_uio_iovcnt(u) (u)->uio_iovcnt | |
90 | #define zfs_uio_iovlen(u, idx) (u)->uio_iov[(idx)].iov_len | |
91 | #define zfs_uio_iovbase(u, idx) (u)->uio_iov[(idx)].iov_base | |
92 | #define zfs_uio_fault_disable(u, set) (u)->uio_fault_disable = set | |
93 | #define zfs_uio_rlimit_fsize(z, u) (0) | |
94 | #define zfs_uio_fault_move(p, n, rw, u) zfs_uiomove((p), (n), (rw), (u)) | |
73e540a0 | 95 | |
c0801bf3 BA |
96 | extern int zfs_uio_prefaultpages(ssize_t, zfs_uio_t *); |
97 | ||
d0cd9a5c BA |
98 | static inline void |
99 | zfs_uio_setoffset(zfs_uio_t *uio, offset_t off) | |
100 | { | |
101 | uio->uio_loffset = off; | |
102 | } | |
883a40ff | 103 | |
883a40ff | 104 | static inline void |
d0cd9a5c | 105 | zfs_uio_advance(zfs_uio_t *uio, size_t size) |
883a40ff JL |
106 | { |
107 | uio->uio_resid -= size; | |
108 | uio->uio_loffset += size; | |
109 | } | |
110 | ||
1c2358c1 | 111 | static inline void |
d0cd9a5c BA |
112 | zfs_uio_iovec_init(zfs_uio_t *uio, const struct iovec *iov, |
113 | unsigned long nr_segs, offset_t offset, zfs_uio_seg_t seg, ssize_t resid, | |
114 | size_t skip) | |
1c2358c1 BB |
115 | { |
116 | ASSERT(seg == UIO_USERSPACE || seg == UIO_SYSSPACE); | |
117 | ||
118 | uio->uio_iov = iov; | |
119 | uio->uio_iovcnt = nr_segs; | |
120 | uio->uio_loffset = offset; | |
121 | uio->uio_segflg = seg; | |
122 | uio->uio_fault_disable = B_FALSE; | |
123 | uio->uio_fmode = 0; | |
124 | uio->uio_extflg = 0; | |
125 | uio->uio_resid = resid; | |
126 | uio->uio_skip = skip; | |
127 | } | |
128 | ||
129 | static inline void | |
6f73d021 | 130 | zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq) |
1c2358c1 | 131 | { |
6f73d021 TH |
132 | /* Either bio or rq will be set, but not both */ |
133 | ASSERT3P(uio, !=, bio); | |
134 | ||
135 | if (bio) { | |
136 | uio->uio_iovcnt = bio->bi_vcnt - BIO_BI_IDX(bio); | |
137 | uio->uio_bvec = &bio->bi_io_vec[BIO_BI_IDX(bio)]; | |
138 | } else { | |
139 | uio->uio_bvec = NULL; | |
140 | uio->uio_iovcnt = 0; | |
141 | memset(&uio->iter, 0, sizeof (uio->iter)); | |
142 | } | |
143 | ||
144 | uio->uio_loffset = io_offset(bio, rq); | |
1c2358c1 BB |
145 | uio->uio_segflg = UIO_BVEC; |
146 | uio->uio_fault_disable = B_FALSE; | |
147 | uio->uio_fmode = 0; | |
148 | uio->uio_extflg = 0; | |
6f73d021 TH |
149 | uio->uio_resid = io_size(bio, rq); |
150 | if (bio) { | |
151 | uio->uio_skip = BIO_BI_SKIP(bio); | |
152 | } else { | |
153 | uio->uio_skip = 0; | |
154 | } | |
155 | ||
156 | uio->rq = rq; | |
1c2358c1 BB |
157 | } |
158 | ||
159 | #if defined(HAVE_VFS_IOV_ITER) | |
160 | static inline void | |
d0cd9a5c | 161 | zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset, |
1c2358c1 BB |
162 | ssize_t resid, size_t skip) |
163 | { | |
164 | uio->uio_iter = iter; | |
165 | uio->uio_iovcnt = iter->nr_segs; | |
166 | uio->uio_loffset = offset; | |
167 | uio->uio_segflg = UIO_ITER; | |
168 | uio->uio_fault_disable = B_FALSE; | |
169 | uio->uio_fmode = 0; | |
170 | uio->uio_extflg = 0; | |
171 | uio->uio_resid = resid; | |
172 | uio->uio_skip = skip; | |
173 | } | |
174 | #endif | |
175 | ||
0bf2c536 CK |
176 | #if defined(HAVE_ITER_IOV) |
177 | #define zfs_uio_iter_iov(iter) iter_iov((iter)) | |
178 | #else | |
179 | #define zfs_uio_iter_iov(iter) (iter)->iov | |
180 | #endif | |
181 | ||
8be6308e CK |
182 | #if defined(HAVE_IOV_ITER_TYPE) |
183 | #define zfs_uio_iov_iter_type(iter) iov_iter_type((iter)) | |
184 | #else | |
185 | #define zfs_uio_iov_iter_type(iter) (iter)->type | |
186 | #endif | |
187 | ||
6adf99e7 | 188 | #endif /* SPL_UIO_H */ |