1 /* $NetBSD: filecore_utils.c,v 1.9 2008/04/30 14:07:14 ad Exp $ */
4 * Copyright (c) 1994 The Regents of the University of California.
7 * This code includes code derived from software contributed to the
8 * NetBSD project by Mark Brinicombe.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
34 * filecore_utils.c 1.1 1998/6/26
38 * Copyright (c) 1998 Andrew McMurry
40 * This code includes code derived from software contributed to the
41 * NetBSD project by Mark Brinicombe.
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the University of
54 * California, Berkeley and its contributors.
55 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission.
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * filecore_utils.c 1.1 1998/6/26
75 * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved.
77 * Redistribution and use in source and binary forms, with or without
78 * modification, are permitted provided that the following conditions
80 * 1. Redistributions of source code must retain the above copyright
81 * notice, this list of conditions and the following disclaimer.
82 * 2. Redistributions in binary form must reproduce the above copyright
83 * notice, this list of conditions and the following disclaimer in the
84 * documentation and/or other materials provided with the distribution.
85 * 3. All advertising materials mentioning features or use of this software
86 * must display the following acknowledgement:
87 * This product includes software developed by Christopher G. Demetriou
88 * for the NetBSD Project.
89 * 4. The name of the author may not be used to endorse or promote products
90 * derived from this software without specific prior written permission
92 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104 #include <sys/cdefs.h>
105 __KERNEL_RCSID(0, "$NetBSD: filecore_utils.c,v 1.9 2008/04/30 14:07:14 ad Exp $");
107 #include <sys/param.h>
108 #include <sys/systm.h>
109 #include <sys/stat.h>
111 #include <sys/mount.h>
112 #include <sys/vnode.h>
113 #include <sys/dirent.h>
114 #include <sys/kauth.h>
116 #include <fs/filecorefs/filecore.h>
117 #include <fs/filecorefs/filecore_extern.h>
118 #include <fs/filecorefs/filecore_node.h>
119 #include <fs/filecorefs/filecore_mount.h>
122 * int filecore_bbchecksum(u_char *bootblock)
124 * Calculates the filecore boot block checksum. This is used to validate
125 * a filecore boot block on the disk. If a boot block is validated then
126 * it is used to locate the partition table. If the boot block is not
127 * validated, it is assumed that the whole disk is NetBSD.
129 * The basic algorithm is:
131 * for (each byte in block, excluding checksum) {
137 * That's equivalent to summing all of the bytes in the block
138 * (excluding the checksum byte, of course), then calculating the
139 * checksum as "cksum = sum - ((sum - 1) / 255) * 255)". That
140 * expression may or may not yield a faster checksum function,
141 * but it's easier to reason about.
143 * Note that if you have a block filled with bytes of a single
144 * value "X" (regardless of that value!) and calculate the cksum
145 * of the block (excluding the checksum byte), you will _always_
146 * end up with a checksum of X. (Do the math; that can be derived
147 * from the checksum calculation function!) That means that
148 * blocks which contain bytes which all have the same value will
149 * always checksum properly. That's a _very_ unlikely occurence
150 * (probably impossible, actually) for a valid filecore boot block,
151 * so we treat such blocks as invalid.
154 filecore_bbchecksum(void *bb
)
156 u_char
*bootblock
= bb
;
157 u_char byte0
, accum_diff
;
163 byte0
= bootblock
[0];
166 * Sum the contents of the block, keeping track of whether
167 * or not all bytes are the same. If 'accum_diff' ends up
168 * being zero, all of the bytes are, in fact, the same.
170 for (i
= 0; i
< 511; ++i
) {
172 accum_diff
|= bootblock
[i
] ^ byte0
;
176 * Check to see if the checksum byte is the same as the
177 * rest of the bytes, too. (Note that if all of the bytes
178 * are the same except the checksum, a checksum compare
179 * won't succeed, but that's not our problem.)
181 accum_diff
|= bootblock
[i
] ^ byte0
;
182 sum
= (sum
- ((sum
- 1) / 255) * 255);
185 * If all bytes in block are the same
186 * or the checksum does not match ; call it invalid.
188 if (accum_diff
== 0 || sum
!= bootblock
[511])
194 filecore_mode(struct filecore_node
*ip
)
199 if ((ip
->i_dirent
.attr
& FILECORE_ATTR_READ
) ||
200 (ip
->i_mnt
->fc_mntflags
& FILECOREMNT_OWNREAD
) ||
201 (ip
->i_dirent
.attr
& FILECORE_ATTR_DIR
))
203 if (ip
->i_mnt
->fc_mntflags
& FILECOREMNT_ALLACCESS
) {
204 m
|= S_IRUSR
| S_IXUSR
;
205 if (rf
|| (ip
->i_dirent
.attr
& FILECORE_ATTR_OREAD
))
206 m
|= S_IRGRP
| S_IXGRP
| S_IROTH
| S_IXOTH
;
207 } else if (ip
->i_mnt
->fc_mntflags
& FILECOREMNT_OWNACCESS
) {
208 if (rf
) m
|= S_IRUSR
| S_IXUSR
;
209 if (ip
->i_dirent
.attr
& FILECORE_ATTR_OREAD
)
210 m
|= S_IRGRP
| S_IXGRP
| S_IROTH
| S_IXOTH
;
212 m
|= S_IRUSR
| S_IXUSR
;
213 if (rf
) m
|= S_IRGRP
| S_IXGRP
;
214 if (ip
->i_dirent
.attr
& FILECORE_ATTR_OREAD
)
215 m
|= S_IROTH
| S_IXOTH
;
217 if (ip
->i_dirent
.attr
& FILECORE_ATTR_DIR
) {
218 m
|= S_IFDIR
| S_IXUSR
| S_IXGRP
| S_IXOTH
;
225 filecore_time(struct filecore_node
*ip
)
230 cs
= (((u_int64_t
)(ip
->i_dirent
.load
& 0xFF)) << 32)
231 + ip
->i_dirent
.exec
- ((u_int64_t
)1725772500 << 7);
232 ts
.tv_sec
= cs
/ 100;
233 ts
.tv_nsec
= (cs
% 100) * 10000000;
238 filecore_getparent(struct filecore_node
*ip
)
246 #ifdef FILECORE_DEBUG
247 printf("filecore_getparent(ino=%llx)\n", (long long)ip
->i_number
);
249 if (ip
->i_parent
!= -2) {
252 if (ip
->i_number
== FILECORE_ROOTINO
) {
253 ip
->i_parent
= ip
->i_number
;
256 addr
= ip
->i_number
& FILECORE_INO_MASK
;
257 /* Read directory data for parent dir to find its parent */
258 #ifdef FILECORE_DEBUG
259 printf("filecore_getparent() read parent dir contents\n");
261 error
= filecore_bread(ip
->i_mnt
, addr
, FILECORE_DIR_SIZE
,
267 paddr
= fcdirtail(pbp
->b_data
)->parent1
268 | fcdirtail(pbp
->b_data
)->parent2
<< 16;
269 #ifdef FILECORE_DEBUG_BR
270 printf("brelse(%p) ut1\n", pbp
);
274 /* If parent's parent is the parent then parent is root dir */
276 ip
->i_parent
= FILECORE_ROOTINO
;
277 return FILECORE_ROOTINO
;
280 #ifdef FILECORE_DEBUG
281 printf("filecore_getparent() read grand-parent dir contents\n");
283 error
= filecore_bread(ip
->i_mnt
, paddr
, FILECORE_DIR_SIZE
,
289 while (fcdirentry(pbp
->b_data
,i
)->addr
!= addr
) {
290 if (fcdirentry(pbp
->b_data
, i
++)->name
[0] == 0) {
291 #ifdef FILECORE_DEBUG_BR
292 printf("brelse(%p) ut2\n", pbp
);
295 return FILECORE_ROOTINO
;
298 #ifdef FILECORE_DEBUG_BR
299 printf("brelse(%p) ut3\n", pbp
);
302 ip
->i_parent
= paddr
+ (i
<< FILECORE_INO_INDEX
);
303 return (paddr
+ (i
<< FILECORE_INO_INDEX
));
307 filecore_fn2unix(char *fcfn
, char *ufn
, u_int16_t
*len
)
313 while (i
++ < 10 && *fcfn
>= ' ') {
321 if (ip
->i_mnt
->fc_mntflags
& FILECOREMNT_FILETYPE
) {
323 *ufn
++ = hexdigits
[(ip
->i_dirent
.load
>> 10) & 15];
324 *ufn
++ = hexdigits
[(ip
->i_dirent
.load
>> 9) & 15];
325 *ufn
++ = hexdigits
[(ip
->i_dirent
.load
>> 8) & 15];
334 filecore_fncmp(const char *fcfn
, const char *ufn
, u_short len
)
339 if (*fcfn
== 0 || len
> 10)
348 if (u
>= 'a' && u
<= 'z') u
-= 'a' - 'A';
349 if (f
>= 'a' && f
<= 'z') f
-= 'a' - 'A';
355 if (len
== 10 || *fcfn
< ' ')