FreeBSD/Linux Kernel Cross Reference
sys/fs/adosfs/adutil.c
1 /* $NetBSD: adutil.c,v 1.3 2005/02/26 22:58:54 perry Exp $ */
2
3 /*
4 * Copyright (c) 1994 Christian E. Hopps
5 * Copyright (c) 1996 Matthias Scheler
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Christian E. Hopps.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.3 2005/02/26 22:58:54 perry Exp $");
36
37 #include <sys/param.h>
38 #include <sys/vnode.h>
39 #include <sys/mount.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
43 #include <sys/time.h>
44 #include <sys/queue.h>
45 #include <sys/buf.h>
46 #include <fs/adosfs/adosfs.h>
47
48 /*
49 * look for anode in the mount's hash table, return locked.
50 */
51 #define AHASH(an) ((an) & (ANODEHASHSZ - 1))
52 static int CapitalChar __P((int, int));
53
54 extern struct simplelock adosfs_hashlock;
55
56 struct vnode *
57 adosfs_ahashget(mp, an)
58 struct mount *mp;
59 ino_t an;
60 {
61 struct anodechain *hp;
62 struct anode *ap;
63 struct vnode *vp;
64
65 hp = &VFSTOADOSFS(mp)->anodetab[AHASH(an)];
66
67 start_over:
68 simple_lock(&adosfs_hashlock);
69 for (ap = hp->lh_first; ap != NULL; ap = ap->link.le_next) {
70 if (ap->block == an) {
71 vp = ATOV(ap);
72 simple_lock(&vp->v_interlock);
73 simple_unlock(&adosfs_hashlock);
74 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
75 goto start_over;
76 return (ATOV(ap));
77 }
78 }
79 simple_unlock(&adosfs_hashlock);
80 return (NULL);
81 }
82
83 /*
84 * insert in hash table and lock
85 *
86 * ap->vp must have been initialized before this call.
87 */
88 void
89 adosfs_ainshash(amp, ap)
90 struct adosfsmount *amp;
91 struct anode *ap;
92 {
93 lockmgr(&ap->vp->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
94
95 simple_lock(&adosfs_hashlock);
96 LIST_INSERT_HEAD(&->anodetab[AHASH(ap->block)], ap, link);
97 simple_unlock(&adosfs_hashlock);
98 }
99
100 void
101 adosfs_aremhash(ap)
102 struct anode *ap;
103 {
104 simple_lock(&adosfs_hashlock);
105 LIST_REMOVE(ap, link);
106 simple_unlock(&adosfs_hashlock);
107 }
108
109 int
110 adosfs_getblktype(amp, bp)
111 struct adosfsmount *amp;
112 struct buf *bp;
113 {
114 if (adoscksum(bp, amp->nwords)) {
115 #ifdef DIAGNOSTIC
116 printf("adosfs: aget: cksum of blk %" PRId64 " failed\n",
117 bp->b_blkno / (amp->bsize / DEV_BSIZE));
118 #endif
119 return (-1);
120 }
121
122 /*
123 * check primary block type
124 */
125 if (adoswordn(bp, 0) != BPT_SHORT) {
126 #ifdef DIAGNOSTIC
127 printf("adosfs: aget: bad primary type blk %" PRId64 " (type = %d)\n",
128 bp->b_blkno / (amp->bsize / DEV_BSIZE), adoswordn(bp,0));
129 #endif
130 return (-1);
131 }
132
133 /*
134 * Check secondary block type.
135 */
136 switch (adoswordn(bp, amp->nwords - 1)) {
137 case BST_RDIR: /* root block */
138 return (AROOT);
139 case BST_LDIR: /* hard link to dir */
140 return (ALDIR);
141 case BST_UDIR: /* user dir */
142 return (ADIR);
143 case BST_LFILE: /* hard link to file */
144 return (ALFILE);
145 case BST_FILE: /* file header */
146 return (AFILE);
147 case BST_SLINK: /* soft link */
148 return (ASLINK);
149 }
150
151 #ifdef DIAGNOSTIC
152 printf("adosfs: aget: bad secondary type blk %" PRId64 " (type = %d)\n",
153 bp->b_blkno / (amp->bsize / DEV_BSIZE), adoswordn(bp, amp->nwords - 1));
154 #endif
155
156 return (-1);
157 }
158
159 int
160 adunixprot(adprot)
161 int adprot;
162 {
163 if (adprot & 0xc000ee00) {
164 adprot = (adprot & 0xee0e) >> 1;
165 return (((adprot & 0x7) << 6) |
166 ((adprot & 0x700) >> 5) |
167 ((adprot & 0x7000) >> 12));
168 }
169 else {
170 adprot = (adprot >> 1) & 0x7;
171 return((adprot << 6) | (adprot << 3) | adprot);
172 }
173 }
174
175 static int
176 CapitalChar(ch, inter)
177 int ch, inter;
178 {
179 if ((ch >= 'a' && ch <= 'z') ||
180 (inter && ch >= 0xe0 && ch <= 0xfe && ch != 0xf7))
181 return(ch - ('a' - 'A'));
182 return(ch);
183 }
184
185 u_int32_t
186 adoscksum(bp, n)
187 struct buf *bp;
188 int n;
189 {
190 u_int32_t sum, *lp;
191
192 lp = (u_int32_t *)bp->b_data;
193 sum = 0;
194
195 while (n--)
196 sum += ntohl(*lp++);
197 return(sum);
198 }
199
200 int
201 adoscaseequ(name1, name2, len, inter)
202 const u_char *name1, *name2;
203 int len, inter;
204 {
205 while (len-- > 0)
206 if (CapitalChar(*name1++, inter) !=
207 CapitalChar(*name2++, inter))
208 return 0;
209
210 return 1;
211 }
212
213 int
214 adoshash(nam, namlen, nelt, inter)
215 const u_char *nam;
216 int namlen, nelt, inter;
217 {
218 int val;
219
220 val = namlen;
221 while (namlen--)
222 val = ((val * 13) + CapitalChar(*nam++, inter)) & 0x7ff;
223 return(val % nelt);
224 }
225
226 #ifdef notyet
227 /*
228 * datestamp is local time, tv is to be UTC
229 */
230 int
231 dstotv(dsp, tvp)
232 struct datestamp *dsp;
233 struct timeval *tvp;
234 {
235 }
236
237 /*
238 * tv is UTC, datestamp is to be local time
239 */
240 int
241 tvtods(tvp, dsp)
242 struct timeval *tvp;
243 struct datestamp *dsp;
244 {
245 }
246 #endif
247
248 #if BYTE_ORDER != BIG_ENDIAN
249 u_int32_t
250 adoswordn(bp, wn)
251 struct buf *bp;
252 int wn;
253 {
254 /*
255 * ados stored in network (big endian) order
256 */
257 return(ntohl(*((u_int32_t *)bp->b_data + wn)));
258 }
259 #endif
Cache object: f6ab8d9b5961a8fd9b0c6a4a468cc735
|