]> git.proxmox.com Git - mirror_zfs.git/blobdiff - include/os/linux/spl/sys/uio.h
dmu: Allow buffer fills to fail
[mirror_zfs.git] / include / os / linux / spl / sys / uio.h
index abcd90dd570cae133686e451800178543f9d05ec..5e6ea8d3c22124a0f13ce472a8097474e39127b7 100644 (file)
 #include <asm/uaccess.h>
 #include <sys/types.h>
 
+#if defined(HAVE_VFS_IOV_ITER) && defined(HAVE_FAULT_IN_IOV_ITER_READABLE)
+#define        iov_iter_fault_in_readable(a, b)        fault_in_iov_iter_readable(a, b)
+#endif
+
 typedef struct iovec iovec_t;
 
-typedef enum uio_rw {
+typedef enum zfs_uio_rw {
        UIO_READ =              0,
        UIO_WRITE =             1,
-} uio_rw_t;
+} zfs_uio_rw_t;
 
-typedef enum uio_seg {
+typedef enum zfs_uio_seg {
        UIO_USERSPACE =         0,
        UIO_SYSSPACE =          1,
-       UIO_USERISPACE =        2,
-       UIO_BVEC =              3,
-} uio_seg_t;
+       UIO_BVEC =              2,
+#if defined(HAVE_VFS_IOV_ITER)
+       UIO_ITER =              3,
+#endif
+} zfs_uio_seg_t;
 
-typedef struct uio {
+typedef struct zfs_uio {
        union {
                const struct iovec      *uio_iov;
                const struct bio_vec    *uio_bvec;
+#if defined(HAVE_VFS_IOV_ITER)
+               struct iov_iter         *uio_iter;
+#endif
        };
        int             uio_iovcnt;
        offset_t        uio_loffset;
-       uio_seg_t       uio_segflg;
+       zfs_uio_seg_t   uio_segflg;
        boolean_t       uio_fault_disable;
        uint16_t        uio_fmode;
        uint16_t        uio_extflg;
-       offset_t        uio_limit;
        ssize_t         uio_resid;
-       size_t          uio_skip;
-} uio_t;
 
-typedef struct aio_req {
-       uio_t           *aio_uio;
-       void            *aio_private;
-} aio_req_t;
-
-typedef enum xuio_type {
-       UIOTYPE_ASYNCIO,
-       UIOTYPE_ZEROCOPY,
-} xuio_type_t;
+       size_t          uio_skip;
 
+       struct request  *rq;
+} zfs_uio_t;
 
-#define        UIOA_IOV_MAX    16
 
-typedef struct uioa_page_s {
-       int     uioa_pfncnt;
-       void    **uioa_ppp;
-       caddr_t uioa_base;
-       size_t  uioa_len;
-} uioa_page_t;
+#define        zfs_uio_segflg(u)               (u)->uio_segflg
+#define        zfs_uio_offset(u)               (u)->uio_loffset
+#define        zfs_uio_resid(u)                (u)->uio_resid
+#define        zfs_uio_iovcnt(u)               (u)->uio_iovcnt
+#define        zfs_uio_iovlen(u, idx)          (u)->uio_iov[(idx)].iov_len
+#define        zfs_uio_iovbase(u, idx)         (u)->uio_iov[(idx)].iov_base
+#define        zfs_uio_fault_disable(u, set)   (u)->uio_fault_disable = set
+#define        zfs_uio_rlimit_fsize(z, u)      (0)
+#define        zfs_uio_fault_move(p, n, rw, u) zfs_uiomove((p), (n), (rw), (u))
 
-typedef struct xuio {
-       uio_t xu_uio;
-       enum xuio_type xu_type;
-       union {
-               struct {
-                       uint32_t xu_a_state;
-                       ssize_t xu_a_mbytes;
-                       uioa_page_t *xu_a_lcur;
-                       void **xu_a_lppp;
-                       void *xu_a_hwst[4];
-                       uioa_page_t xu_a_locked[UIOA_IOV_MAX];
-               } xu_aio;
-
-               struct {
-                       int xu_zc_rw;
-                       void *xu_zc_priv;
-               } xu_zc;
-       } xu_ext;
-} xuio_t;
-
-#define        XUIO_XUZC_PRIV(xuio)    xuio->xu_ext.xu_zc.xu_zc_priv
-#define        XUIO_XUZC_RW(xuio)      xuio->xu_ext.xu_zc.xu_zc_rw
-
-#define        uio_segflg(uio)                 (uio)->uio_segflg
-#define        uio_offset(uio)                 (uio)->uio_loffset
-#define        uio_resid(uio)                  (uio)->uio_resid
-#define        uio_iovcnt(uio)                 (uio)->uio_iovcnt
-#define        uio_iovlen(uio, idx)            (uio)->uio_iov[(idx)].iov_len
-#define        uio_iovbase(uio, idx)           (uio)->uio_iov[(idx)].iov_base
+extern int zfs_uio_prefaultpages(ssize_t, zfs_uio_t *);
 
 static inline void
-uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len)
+zfs_uio_setoffset(zfs_uio_t *uio, offset_t off)
 {
-       *base = uio_iovbase(uio, idx);
-       *len = uio_iovlen(uio, idx);
+       uio->uio_loffset = off;
 }
 
 static inline void
-uio_advance(uio_t *uio, size_t size)
+zfs_uio_advance(zfs_uio_t *uio, ssize_t size)
 {
        uio->uio_resid -= size;
        uio->uio_loffset += size;
 }
 
-static inline offset_t
-uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx)
+static inline void
+zfs_uio_iovec_init(zfs_uio_t *uio, const struct iovec *iov,
+    unsigned long nr_segs, offset_t offset, zfs_uio_seg_t seg, ssize_t resid,
+    size_t skip)
+{
+       ASSERT(seg == UIO_USERSPACE || seg == UIO_SYSSPACE);
+
+       uio->uio_iov = iov;
+       uio->uio_iovcnt = nr_segs;
+       uio->uio_loffset = offset;
+       uio->uio_segflg = seg;
+       uio->uio_fault_disable = B_FALSE;
+       uio->uio_fmode = 0;
+       uio->uio_extflg = 0;
+       uio->uio_resid = resid;
+       uio->uio_skip = skip;
+}
+
+static inline void
+zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq)
 {
-       *vec_idx = 0;
-       while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) {
-               off -= uio_iovlen(uio, *vec_idx);
-               (*vec_idx)++;
+       /* Either bio or rq will be set, but not both */
+       ASSERT3P(uio, !=, bio);
+
+       if (bio) {
+               uio->uio_iovcnt = bio->bi_vcnt - BIO_BI_IDX(bio);
+               uio->uio_bvec = &bio->bi_io_vec[BIO_BI_IDX(bio)];
+       } else {
+               uio->uio_bvec = NULL;
+               uio->uio_iovcnt = 0;
+       }
+
+       uio->uio_loffset = io_offset(bio, rq);
+       uio->uio_segflg = UIO_BVEC;
+       uio->uio_fault_disable = B_FALSE;
+       uio->uio_fmode = 0;
+       uio->uio_extflg = 0;
+       uio->uio_resid = io_size(bio, rq);
+       if (bio) {
+               uio->uio_skip = BIO_BI_SKIP(bio);
+       } else {
+               uio->uio_skip = 0;
        }
 
-       return (off);
+       uio->rq = rq;
+}
+
+#if defined(HAVE_VFS_IOV_ITER)
+static inline void
+zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
+    ssize_t resid, size_t skip)
+{
+       uio->uio_iter = iter;
+       uio->uio_iovcnt = iter->nr_segs;
+       uio->uio_loffset = offset;
+       uio->uio_segflg = UIO_ITER;
+       uio->uio_fault_disable = B_FALSE;
+       uio->uio_fmode = 0;
+       uio->uio_extflg = 0;
+       uio->uio_resid = resid;
+       uio->uio_skip = skip;
 }
+#endif
+
+#if defined(HAVE_ITER_IOV)
+#define        zfs_uio_iter_iov(iter)  iter_iov((iter))
+#else
+#define        zfs_uio_iter_iov(iter)  (iter)->iov
+#endif
+
+#if defined(HAVE_IOV_ITER_TYPE)
+#define        zfs_uio_iov_iter_type(iter)     iov_iter_type((iter))
+#else
+#define        zfs_uio_iov_iter_type(iter)     (iter)->type
+#endif
 
 #endif /* SPL_UIO_H */