1 /*        $NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $          */
2 
3 /*-
4  * Copyright (c) 1990, 1993, 1994
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Mike Olson.
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  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #if HAVE_NBTOOL_CONFIG_H
36 #include "nbtool_config.h"
37 #endif
38 
39 #include <sys/cdefs.h>
40 __RCSID("$NetBSD: bt_conv.c,v 1.15 2016/09/24 20:11:12 christos Exp $");
41 
42 #include <assert.h>
43 #include <stdio.h>
44 #include <memory.h>
45 
46 #include <db.h>
47 #include "btree.h"
48 
49 static void mswap(PAGE *);
50 
51 /*
52  * __BT_BPGIN, __BT_BPGOUT --
53  *        Convert host-specific number layout to/from the host-independent
54  *        format stored on disk.
55  *
56  * Parameters:
57  *        t:        tree
58  *        pg:       page number
59  *        h:        page to convert
60  */
61 void
__bt_pgin(void * t,pgno_t pg,void * pp)62 __bt_pgin(void *t, pgno_t pg, void *pp)
63 {
64           PAGE *h;
65           indx_t i, top;
66           uint8_t flags;
67           char *p;
68           uint32_t ksize;
69 
70           if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
71                     return;
72           if (pg == P_META) {
73                     mswap(pp);
74                     return;
75           }
76 
77           h = pp;
78           M_32_SWAP(h->pgno);
79           M_32_SWAP(h->prevpg);
80           M_32_SWAP(h->nextpg);
81           M_32_SWAP(h->flags);
82           M_16_SWAP(h->lower);
83           M_16_SWAP(h->upper);
84 
85           top = NEXTINDEX(h);
86           if ((h->flags & P_TYPE) == P_BINTERNAL)
87                     for (i = 0; i < top; i++) {
88                               M_16_SWAP(h->linp[i]);
89                               p = (char *)(void *)GETBINTERNAL(h, i);
90                               P_32_SWAP(p);
91                               p += sizeof(uint32_t);
92                               P_32_SWAP(p);
93                               p += sizeof(pgno_t);
94                               if (*(uint8_t *)p & P_BIGKEY) {
95                                         p += sizeof(uint8_t);
96                                         P_32_SWAP(p);
97                                         p += sizeof(pgno_t);
98                                         P_32_SWAP(p);
99                               }
100                     }
101           else if ((h->flags & P_TYPE) == P_BLEAF)
102                     for (i = 0; i < top; i++) {
103                               M_16_SWAP(h->linp[i]);
104                               p = (char *)(void *)GETBLEAF(h, i);
105                               P_32_SWAP(p);
106                               memcpy(&ksize, p, sizeof(ksize));
107                               p += sizeof(uint32_t);
108                               P_32_SWAP(p);
109                               p += sizeof(uint32_t);
110                               flags = *(uint8_t *)p;
111                               if (flags & (P_BIGKEY | P_BIGDATA)) {
112                                         p += sizeof(uint8_t);
113                                         if (flags & P_BIGKEY) {
114                                                   P_32_SWAP(p);
115                                                   p += sizeof(pgno_t);
116                                                   P_32_SWAP(p);
117                                         }
118                                         if (flags & P_BIGDATA) {
119                                                   p += ksize;
120                                                   P_32_SWAP(p);
121                                                   p += sizeof(pgno_t);
122                                                   P_32_SWAP(p);
123                                         }
124                               }
125                     }
126 }
127 
128 void
__bt_pgout(void * t,pgno_t pg,void * pp)129 __bt_pgout(void *t, pgno_t pg, void *pp)
130 {
131           PAGE *h;
132           indx_t i, top;
133           uint8_t flags;
134           char *p;
135           uint32_t ksize;
136 
137           if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
138                     return;
139           if (pg == P_META) {
140                     mswap(pp);
141                     return;
142           }
143 
144           h = pp;
145           top = NEXTINDEX(h);
146           if ((h->flags & P_TYPE) == P_BINTERNAL)
147                     for (i = 0; i < top; i++) {
148                               p = (char *)(void *)GETBINTERNAL(h, i);
149                               P_32_SWAP(p);
150                               p += sizeof(uint32_t);
151                               P_32_SWAP(p);
152                               p += sizeof(pgno_t);
153                               if (*(uint8_t *)p & P_BIGKEY) {
154                                         p += sizeof(uint8_t);
155                                         P_32_SWAP(p);
156                                         p += sizeof(pgno_t);
157                                         P_32_SWAP(p);
158                               }
159                               M_16_SWAP(h->linp[i]);
160                     }
161           else if ((h->flags & P_TYPE) == P_BLEAF)
162                     for (i = 0; i < top; i++) {
163                               p = (char *)(void *)GETBLEAF(h, i);
164                               ksize = GETBLEAF(h, i)->ksize;
165                               P_32_SWAP(p);
166                               p += sizeof(uint32_t);
167                               P_32_SWAP(p);
168                               p += sizeof(uint32_t);
169                               flags = *(uint8_t *)p;
170                               if (flags & (P_BIGKEY | P_BIGDATA)) {
171                                         p += sizeof(uint8_t);
172                                         if (flags & P_BIGKEY) {
173                                                   P_32_SWAP(p);
174                                                   p += sizeof(pgno_t);
175                                                   P_32_SWAP(p);
176                                         }
177                                         if (flags & P_BIGDATA) {
178                                                   p += ksize;
179                                                   P_32_SWAP(p);
180                                                   p += sizeof(pgno_t);
181                                                   P_32_SWAP(p);
182                                         }
183                               }
184                               M_16_SWAP(h->linp[i]);
185                     }
186 
187           M_32_SWAP(h->pgno);
188           M_32_SWAP(h->prevpg);
189           M_32_SWAP(h->nextpg);
190           M_32_SWAP(h->flags);
191           M_16_SWAP(h->lower);
192           M_16_SWAP(h->upper);
193 }
194 
195 /*
196  * MSWAP -- Actually swap the bytes on the meta page.
197  *
198  * Parameters:
199  *        p:        page to convert
200  */
201 static void
mswap(PAGE * pg)202 mswap(PAGE *pg)
203 {
204           char *p;
205 
206           p = (char *)(void *)pg;
207           P_32_SWAP(p);                 /* magic */
208           p += sizeof(uint32_t);
209           P_32_SWAP(p);                 /* version */
210           p += sizeof(uint32_t);
211           P_32_SWAP(p);                 /* psize */
212           p += sizeof(uint32_t);
213           P_32_SWAP(p);                 /* free */
214           p += sizeof(uint32_t);
215           P_32_SWAP(p);                 /* nrecs */
216           p += sizeof(uint32_t);
217           P_32_SWAP(p);                 /* flags */
218           p += sizeof(uint32_t);
219 }
220