1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2022 Tomohiro Kusumi <tkusumi@netbsd.org> 5 * Copyright (c) 2011-2022 The DragonFly Project. All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Matthew Dillon <dillon@dragonflybsd.org> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 3. Neither the name of The DragonFly Project nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific, prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include "hammer2.h" 39 #include "makefs.h" 40 41 struct m_buf * 42 getblkx(struct m_vnode *vp, off_t loffset, int size, int blkflags, int slptimeo) 43 { 44 struct m_buf *bp; 45 makefs_daddr_t blkno; 46 47 if (vp->v_logical) 48 blkno = -1; 49 else 50 blkno = loffset / DEV_BSIZE; /* fsopts->sectorsize */ 51 52 bp = getblk(vp, blkno, size, 0, 0, 0); 53 assert(bp); 54 assert(bp->b_data); 55 56 bp->b_loffset = loffset; 57 58 return (bp); 59 } 60 61 int 62 breadx(struct m_vnode *vp, off_t loffset, int size, struct m_buf **bpp) 63 { 64 struct m_buf *bp; 65 ssize_t ret; 66 67 assert(bpp != NULL); 68 69 bp = getblkx(vp, loffset, size, 0, 0); 70 if (bp->b_fs == NULL) 71 errx(1, "buf %p for vp %p has no makefs_fsinfo", bp, vp); 72 73 assert(bp->b_blkno * DEV_BSIZE == bp->b_loffset); 74 assert(bp->b_bcount == size); 75 assert(bp->b_vp); 76 assert(!bp->b_vp->v_logical); 77 *bpp = bp; 78 79 if (lseek(bp->b_fs->fd, bp->b_loffset, SEEK_SET) == -1) 80 err(1, "%s: lseek vp %p offset 0x%016jx", 81 __func__, vp, (intmax_t)bp->b_loffset); 82 83 ret = read(bp->b_fs->fd, bp->b_data, bp->b_bcount); 84 if (debug & DEBUG_BUF_BREAD) 85 printf("%s: read vp %p offset 0x%016jx size 0x%jx -> 0x%jx\n", 86 __func__, vp, (intmax_t)bp->b_loffset, 87 (intmax_t)bp->b_bcount, (intmax_t)ret); 88 89 if (ret == -1) { 90 err(1, "%s: read vp %p offset 0x%016jx size 0x%jx", 91 __func__, vp, (intmax_t)bp->b_loffset, 92 (intmax_t)bp->b_bcount); 93 } else if (ret != bp->b_bcount) { 94 if (debug) 95 printf("%s: read vp %p offset 0x%016jx size 0x%jx -> " 96 "0x%jx != 0x%jx\n", 97 __func__, vp, (intmax_t)bp->b_loffset, 98 (intmax_t)bp->b_bcount, (intmax_t)ret, 99 (intmax_t)bp->b_bcount); 100 return (EINVAL); 101 } 102 103 return (0); 104 } 105 106 int 107 bread_kvabio(struct m_vnode *vp, off_t loffset, int size, struct m_buf **bpp) 108 { 109 return (breadx(vp, loffset, size, bpp)); 110 } 111 112 void 113 bqrelse(struct m_buf *bp) 114 { 115 brelse(bp); 116 } 117 118 int 119 bawrite(struct m_buf *bp) 120 { 121 return (bwrite(bp)); 122 } 123 124 int 125 uiomove(caddr_t cp, size_t n, struct uio *uio) 126 { 127 struct iovec *iov; 128 size_t cnt; 129 int error = 0; 130 131 KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE, 132 ("uiomove: mode")); 133 134 while (n > 0 && uio->uio_resid) { 135 iov = uio->uio_iov; 136 cnt = iov->iov_len; 137 if (cnt == 0) { 138 uio->uio_iov++; 139 uio->uio_iovcnt--; 140 continue; 141 } 142 if (cnt > n) 143 cnt = n; 144 145 switch (uio->uio_segflg) { 146 case UIO_USERSPACE: 147 /* emulate copyout/copyin */ 148 if (uio->uio_rw == UIO_READ) 149 bcopy(cp, iov->iov_base, cnt); 150 else 151 bcopy(iov->iov_base, cp, cnt); 152 break; 153 case UIO_SYSSPACE: 154 if (uio->uio_rw == UIO_READ) 155 bcopy(cp, iov->iov_base, cnt); 156 else 157 bcopy(iov->iov_base, cp, cnt); 158 break; 159 case UIO_NOCOPY: 160 assert(0); /* no UIO_NOCOPY in makefs */ 161 break; 162 } 163 164 if (error) 165 break; 166 iov->iov_base = (char *)iov->iov_base + cnt; 167 iov->iov_len -= cnt; 168 uio->uio_resid -= cnt; 169 uio->uio_offset += cnt; 170 cp += cnt; 171 n -= cnt; 172 } 173 174 return (error); 175 } 176 177 int 178 uiomovebp(struct m_buf *bp, caddr_t cp, size_t n, struct uio *uio) 179 { 180 return (uiomove(cp, n, uio)); 181 } 182