xref: /dragonfly/usr.sbin/makefs/hammer2/hammer2_buf.c (revision 5e8b0eb766966577a1da788053d7ccaa443fa222)
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 *
getblkx(struct m_vnode * vp,off_t loffset,int size,int blkflags,int slptimeo)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
breadx(struct m_vnode * vp,off_t loffset,int size,struct m_buf ** bpp)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
bread_kvabio(struct m_vnode * vp,off_t loffset,int size,struct m_buf ** bpp)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
bqrelse(struct m_buf * bp)113 bqrelse(struct m_buf *bp)
114 {
115           brelse(bp);
116 }
117 
118 int
bawrite(struct m_buf * bp)119 bawrite(struct m_buf *bp)
120 {
121           return (bwrite(bp));
122 }
123 
124 int
uiomove(caddr_t cp,size_t n,struct uio * uio)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
uiomovebp(struct m_buf * bp,caddr_t cp,size_t n,struct uio * uio)178 uiomovebp(struct m_buf *bp, caddr_t cp, size_t n, struct uio *uio)
179 {
180           return (uiomove(cp, n, uio));
181 }
182