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