xref: /netbsd-src/sys/fs/adosfs/adutil.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: adutil.c,v 1.2 2003/01/27 04:08:45 lonewolf 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.2 2003/01/27 04:08:45 lonewolf 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(&amp->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
260