12d60b848STomohiro Kusumi /*
22d60b848STomohiro Kusumi * SPDX-License-Identifier: BSD-3-Clause
32d60b848STomohiro Kusumi *
42d60b848STomohiro Kusumi * Copyright (c) 2022 Tomohiro Kusumi <tkusumi@netbsd.org>
52d60b848STomohiro Kusumi * Copyright (c) 2011-2022 The DragonFly Project. All rights reserved.
62d60b848STomohiro Kusumi *
72d60b848STomohiro Kusumi * This code is derived from software contributed to The DragonFly Project
82d60b848STomohiro Kusumi * by Matthew Dillon <dillon@dragonflybsd.org>
92d60b848STomohiro Kusumi *
102d60b848STomohiro Kusumi * Redistribution and use in source and binary forms, with or without
112d60b848STomohiro Kusumi * modification, are permitted provided that the following conditions
122d60b848STomohiro Kusumi * are met:
132d60b848STomohiro Kusumi *
142d60b848STomohiro Kusumi * 1. Redistributions of source code must retain the above copyright
152d60b848STomohiro Kusumi * notice, this list of conditions and the following disclaimer.
162d60b848STomohiro Kusumi * 2. Redistributions in binary form must reproduce the above copyright
172d60b848STomohiro Kusumi * notice, this list of conditions and the following disclaimer in
182d60b848STomohiro Kusumi * the documentation and/or other materials provided with the
192d60b848STomohiro Kusumi * distribution.
202d60b848STomohiro Kusumi * 3. Neither the name of The DragonFly Project nor the names of its
212d60b848STomohiro Kusumi * contributors may be used to endorse or promote products derived
222d60b848STomohiro Kusumi * from this software without specific, prior written permission.
232d60b848STomohiro Kusumi *
242d60b848STomohiro Kusumi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
252d60b848STomohiro Kusumi * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
262d60b848STomohiro Kusumi * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
272d60b848STomohiro Kusumi * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
282d60b848STomohiro Kusumi * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
292d60b848STomohiro Kusumi * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
302d60b848STomohiro Kusumi * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
312d60b848STomohiro Kusumi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
322d60b848STomohiro Kusumi * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
332d60b848STomohiro Kusumi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
342d60b848STomohiro Kusumi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
352d60b848STomohiro Kusumi * SUCH DAMAGE.
362d60b848STomohiro Kusumi */
372d60b848STomohiro Kusumi
382d60b848STomohiro Kusumi #include "hammer2.h"
392d60b848STomohiro Kusumi #include "makefs.h"
402d60b848STomohiro Kusumi
414e2eefe9STomohiro Kusumi struct m_buf *
getblkx(struct m_vnode * vp,off_t loffset,int size,int blkflags,int slptimeo)426bcbb706STomohiro Kusumi getblkx(struct m_vnode *vp, off_t loffset, int size, int blkflags, int slptimeo)
432d60b848STomohiro Kusumi {
444e2eefe9STomohiro Kusumi struct m_buf *bp;
45aea8f776STomohiro Kusumi makefs_daddr_t blkno;
46aea8f776STomohiro Kusumi
47aea8f776STomohiro Kusumi if (vp->v_logical)
48aea8f776STomohiro Kusumi blkno = -1;
49aea8f776STomohiro Kusumi else
50aea8f776STomohiro Kusumi blkno = loffset / DEV_BSIZE; /* fsopts->sectorsize */
512d60b848STomohiro Kusumi
522d60b848STomohiro Kusumi bp = getblk(vp, blkno, size, 0, 0, 0);
532d60b848STomohiro Kusumi assert(bp);
542d60b848STomohiro Kusumi assert(bp->b_data);
552d60b848STomohiro Kusumi
562d60b848STomohiro Kusumi bp->b_loffset = loffset;
572d60b848STomohiro Kusumi
582d60b848STomohiro Kusumi return (bp);
592d60b848STomohiro Kusumi }
602d60b848STomohiro Kusumi
612d60b848STomohiro Kusumi int
breadx(struct m_vnode * vp,off_t loffset,int size,struct m_buf ** bpp)624e2eefe9STomohiro Kusumi breadx(struct m_vnode *vp, off_t loffset, int size, struct m_buf **bpp)
632d60b848STomohiro Kusumi {
644e2eefe9STomohiro Kusumi struct m_buf *bp;
652d60b848STomohiro Kusumi ssize_t ret;
662d60b848STomohiro Kusumi
672d60b848STomohiro Kusumi assert(bpp != NULL);
682d60b848STomohiro Kusumi
692d60b848STomohiro Kusumi bp = getblkx(vp, loffset, size, 0, 0);
702d60b848STomohiro Kusumi if (bp->b_fs == NULL)
712d60b848STomohiro Kusumi errx(1, "buf %p for vp %p has no makefs_fsinfo", bp, vp);
722d60b848STomohiro Kusumi
732d60b848STomohiro Kusumi assert(bp->b_blkno * DEV_BSIZE == bp->b_loffset);
742d60b848STomohiro Kusumi assert(bp->b_bcount == size);
752d60b848STomohiro Kusumi assert(bp->b_vp);
76e00b9e51STomohiro Kusumi assert(!bp->b_vp->v_logical);
772d60b848STomohiro Kusumi *bpp = bp;
782d60b848STomohiro Kusumi
792d60b848STomohiro Kusumi if (lseek(bp->b_fs->fd, bp->b_loffset, SEEK_SET) == -1)
802d60b848STomohiro Kusumi err(1, "%s: lseek vp %p offset 0x%016jx",
819e98def1STomohiro Kusumi __func__, vp, (intmax_t)bp->b_loffset);
822d60b848STomohiro Kusumi
832d60b848STomohiro Kusumi ret = read(bp->b_fs->fd, bp->b_data, bp->b_bcount);
842d60b848STomohiro Kusumi if (debug & DEBUG_BUF_BREAD)
852d60b848STomohiro Kusumi printf("%s: read vp %p offset 0x%016jx size 0x%jx -> 0x%jx\n",
86f8a1147cSTomohiro Kusumi __func__, vp, (intmax_t)bp->b_loffset,
87f8a1147cSTomohiro Kusumi (intmax_t)bp->b_bcount, (intmax_t)ret);
882d60b848STomohiro Kusumi
892d60b848STomohiro Kusumi if (ret == -1) {
902d60b848STomohiro Kusumi err(1, "%s: read vp %p offset 0x%016jx size 0x%jx",
91f8a1147cSTomohiro Kusumi __func__, vp, (intmax_t)bp->b_loffset,
92f8a1147cSTomohiro Kusumi (intmax_t)bp->b_bcount);
932d60b848STomohiro Kusumi } else if (ret != bp->b_bcount) {
942d60b848STomohiro Kusumi if (debug)
952d60b848STomohiro Kusumi printf("%s: read vp %p offset 0x%016jx size 0x%jx -> "
962d60b848STomohiro Kusumi "0x%jx != 0x%jx\n",
97f8a1147cSTomohiro Kusumi __func__, vp, (intmax_t)bp->b_loffset,
98f8a1147cSTomohiro Kusumi (intmax_t)bp->b_bcount, (intmax_t)ret,
99f8a1147cSTomohiro Kusumi (intmax_t)bp->b_bcount);
1002d60b848STomohiro Kusumi return (EINVAL);
1012d60b848STomohiro Kusumi }
1022d60b848STomohiro Kusumi
1032d60b848STomohiro Kusumi return (0);
1042d60b848STomohiro Kusumi }
1052d60b848STomohiro Kusumi
1062d60b848STomohiro Kusumi int
bread_kvabio(struct m_vnode * vp,off_t loffset,int size,struct m_buf ** bpp)1074e2eefe9STomohiro Kusumi bread_kvabio(struct m_vnode *vp, off_t loffset, int size, struct m_buf **bpp)
1082d60b848STomohiro Kusumi {
1092d60b848STomohiro Kusumi return (breadx(vp, loffset, size, bpp));
1102d60b848STomohiro Kusumi }
1112d60b848STomohiro Kusumi
1122d60b848STomohiro Kusumi void
bqrelse(struct m_buf * bp)1134e2eefe9STomohiro Kusumi bqrelse(struct m_buf *bp)
1142d60b848STomohiro Kusumi {
1152d60b848STomohiro Kusumi brelse(bp);
1162d60b848STomohiro Kusumi }
1172d60b848STomohiro Kusumi
1182d60b848STomohiro Kusumi int
bawrite(struct m_buf * bp)1194e2eefe9STomohiro Kusumi bawrite(struct m_buf *bp)
1202d60b848STomohiro Kusumi {
1212d60b848STomohiro Kusumi return (bwrite(bp));
1222d60b848STomohiro Kusumi }
1232d60b848STomohiro Kusumi
124*5e8b0eb7STomohiro Kusumi int
uiomove(caddr_t cp,size_t n,struct uio * uio)1252d60b848STomohiro Kusumi uiomove(caddr_t cp, size_t n, struct uio *uio)
1262d60b848STomohiro Kusumi {
1272d60b848STomohiro Kusumi struct iovec *iov;
1282d60b848STomohiro Kusumi size_t cnt;
1292d60b848STomohiro Kusumi int error = 0;
1302d60b848STomohiro Kusumi
1312d60b848STomohiro Kusumi KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
1322d60b848STomohiro Kusumi ("uiomove: mode"));
1332d60b848STomohiro Kusumi
1342d60b848STomohiro Kusumi while (n > 0 && uio->uio_resid) {
1352d60b848STomohiro Kusumi iov = uio->uio_iov;
1362d60b848STomohiro Kusumi cnt = iov->iov_len;
1372d60b848STomohiro Kusumi if (cnt == 0) {
1382d60b848STomohiro Kusumi uio->uio_iov++;
1392d60b848STomohiro Kusumi uio->uio_iovcnt--;
1402d60b848STomohiro Kusumi continue;
1412d60b848STomohiro Kusumi }
1422d60b848STomohiro Kusumi if (cnt > n)
1432d60b848STomohiro Kusumi cnt = n;
1442d60b848STomohiro Kusumi
1452d60b848STomohiro Kusumi switch (uio->uio_segflg) {
1462d60b848STomohiro Kusumi case UIO_USERSPACE:
1472d60b848STomohiro Kusumi /* emulate copyout/copyin */
1482d60b848STomohiro Kusumi if (uio->uio_rw == UIO_READ)
1492d60b848STomohiro Kusumi bcopy(cp, iov->iov_base, cnt);
1502d60b848STomohiro Kusumi else
1512d60b848STomohiro Kusumi bcopy(iov->iov_base, cp, cnt);
1522d60b848STomohiro Kusumi break;
1532d60b848STomohiro Kusumi case UIO_SYSSPACE:
1542d60b848STomohiro Kusumi if (uio->uio_rw == UIO_READ)
1552d60b848STomohiro Kusumi bcopy(cp, iov->iov_base, cnt);
1562d60b848STomohiro Kusumi else
1572d60b848STomohiro Kusumi bcopy(iov->iov_base, cp, cnt);
1582d60b848STomohiro Kusumi break;
1592d60b848STomohiro Kusumi case UIO_NOCOPY:
1602d60b848STomohiro Kusumi assert(0); /* no UIO_NOCOPY in makefs */
1612d60b848STomohiro Kusumi break;
1622d60b848STomohiro Kusumi }
1632d60b848STomohiro Kusumi
1642d60b848STomohiro Kusumi if (error)
1652d60b848STomohiro Kusumi break;
1662d60b848STomohiro Kusumi iov->iov_base = (char *)iov->iov_base + cnt;
1672d60b848STomohiro Kusumi iov->iov_len -= cnt;
1682d60b848STomohiro Kusumi uio->uio_resid -= cnt;
1692d60b848STomohiro Kusumi uio->uio_offset += cnt;
1702d60b848STomohiro Kusumi cp += cnt;
1712d60b848STomohiro Kusumi n -= cnt;
1722d60b848STomohiro Kusumi }
1732d60b848STomohiro Kusumi
1742d60b848STomohiro Kusumi return (error);
1752d60b848STomohiro Kusumi }
1762d60b848STomohiro Kusumi
1772d60b848STomohiro Kusumi int
uiomovebp(struct m_buf * bp,caddr_t cp,size_t n,struct uio * uio)1784e2eefe9STomohiro Kusumi uiomovebp(struct m_buf *bp, caddr_t cp, size_t n, struct uio *uio)
1792d60b848STomohiro Kusumi {
1802d60b848STomohiro Kusumi return (uiomove(cp, n, uio));
1812d60b848STomohiro Kusumi }
182