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 = loffset / DEV_BSIZE; 46 47 bp = getblk(vp, blkno, size, 0, 0, 0); 48 assert(bp); 49 assert(bp->b_data); 50 51 bp->b_loffset = loffset; 52 bp->b_is_hammer2 = 1; 53 54 return (bp); 55 } 56 57 int 58 breadx(struct m_vnode *vp, off_t loffset, int size, struct m_buf **bpp) 59 { 60 struct m_buf *bp; 61 ssize_t ret; 62 63 assert(bpp != NULL); 64 65 bp = getblkx(vp, loffset, size, 0, 0); 66 if (bp->b_fs == NULL) 67 errx(1, "buf %p for vp %p has no makefs_fsinfo", bp, vp); 68 69 assert(bp->b_blkno * DEV_BSIZE == bp->b_loffset); 70 assert(bp->b_bcount == size); 71 assert(bp->b_vp); 72 assert(!bp->b_vp->v_logical); 73 *bpp = bp; 74 75 if (lseek(bp->b_fs->fd, bp->b_loffset, SEEK_SET) == -1) 76 err(1, "%s: lseek vp %p offset 0x%016jx", 77 __func__, vp, (intmax_t)bp->b_loffset); 78 79 ret = read(bp->b_fs->fd, bp->b_data, bp->b_bcount); 80 if (debug & DEBUG_BUF_BREAD) 81 printf("%s: read vp %p offset 0x%016jx size 0x%jx -> 0x%jx\n", 82 __func__, vp, (intmax_t)bp->b_loffset, bp->b_bcount, ret); 83 84 if (ret == -1) { 85 err(1, "%s: read vp %p offset 0x%016jx size 0x%jx", 86 __func__, vp, (intmax_t)bp->b_loffset, bp->b_bcount); 87 } else if (ret != bp->b_bcount) { 88 if (debug) 89 printf("%s: read vp %p offset 0x%016jx size 0x%jx -> " 90 "0x%jx != 0x%jx\n", 91 __func__, vp, (intmax_t)bp->b_loffset, bp->b_bcount, ret, 92 bp->b_bcount); 93 return (EINVAL); 94 } 95 96 return (0); 97 } 98 99 int 100 bread_kvabio(struct m_vnode *vp, off_t loffset, int size, struct m_buf **bpp) 101 { 102 return (breadx(vp, loffset, size, bpp)); 103 } 104 105 void 106 bqrelse(struct m_buf *bp) 107 { 108 brelse(bp); 109 } 110 111 int 112 bawrite(struct m_buf *bp) 113 { 114 return (bwrite(bp)); 115 } 116 117 static int 118 uiomove(caddr_t cp, size_t n, struct uio *uio) 119 { 120 struct iovec *iov; 121 size_t cnt; 122 size_t tot = 0; 123 int error = 0; 124 125 KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE, 126 ("uiomove: mode")); 127 128 while (n > 0 && uio->uio_resid) { 129 iov = uio->uio_iov; 130 cnt = iov->iov_len; 131 if (cnt == 0) { 132 uio->uio_iov++; 133 uio->uio_iovcnt--; 134 continue; 135 } 136 if (cnt > n) 137 cnt = n; 138 tot += cnt; 139 140 switch (uio->uio_segflg) { 141 case UIO_USERSPACE: 142 /* emulate copyout/copyin */ 143 if (uio->uio_rw == UIO_READ) 144 bcopy(cp, iov->iov_base, cnt); 145 else 146 bcopy(iov->iov_base, cp, cnt); 147 break; 148 case UIO_SYSSPACE: 149 if (uio->uio_rw == UIO_READ) 150 bcopy(cp, iov->iov_base, cnt); 151 else 152 bcopy(iov->iov_base, cp, cnt); 153 break; 154 case UIO_NOCOPY: 155 assert(0); /* no UIO_NOCOPY in makefs */ 156 break; 157 } 158 159 if (error) 160 break; 161 iov->iov_base = (char *)iov->iov_base + cnt; 162 iov->iov_len -= cnt; 163 uio->uio_resid -= cnt; 164 uio->uio_offset += cnt; 165 cp += cnt; 166 n -= cnt; 167 } 168 169 return (error); 170 } 171 172 int 173 uiomovebp(struct m_buf *bp, caddr_t cp, size_t n, struct uio *uio) 174 { 175 return (uiomove(cp, n, uio)); 176 } 177