xref: /dflybsd-src/usr.sbin/makefs/hammer2/hammer2_buf.c (revision 5e8b0eb766966577a1da788053d7ccaa443fa222)
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