1 /* $NetBSD: adutil.c,v 1.10 2009/03/14 15:36:21 dsl Exp $ */
4 * Copyright (c) 1994 Christian E. Hopps
5 * Copyright (c) 1996 Matthias Scheler
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
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.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: adutil.c,v 1.10 2009/03/14 15:36:21 dsl Exp $");
37 #include <sys/param.h>
38 #include <sys/vnode.h>
39 #include <sys/mount.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
44 #include <sys/queue.h>
46 #include <sys/simplelock.h>
47 #include <fs/adosfs/adosfs.h>
50 * look for anode in the mount's hash table, return locked.
52 #define AHASH(an) ((an) & (ANODEHASHSZ - 1))
53 static int CapitalChar(int, int);
55 extern struct simplelock adosfs_hashlock
;
58 adosfs_ahashget(struct mount
*mp
, ino_t an
)
60 struct anodechain
*hp
;
64 hp
= &VFSTOADOSFS(mp
)->anodetab
[AHASH(an
)];
67 simple_lock(&adosfs_hashlock
);
68 for (ap
= hp
->lh_first
; ap
!= NULL
; ap
= ap
->link
.le_next
) {
69 if (ap
->block
== an
) {
71 mutex_enter(&vp
->v_interlock
);
72 simple_unlock(&adosfs_hashlock
);
73 if (vget(vp
, LK_EXCLUSIVE
| LK_INTERLOCK
))
78 simple_unlock(&adosfs_hashlock
);
83 * insert in hash table and lock
85 * ap->vp must have been initialized before this call.
88 adosfs_ainshash(struct adosfsmount
*amp
, struct anode
*ap
)
90 vlockmgr(&ap
->vp
->v_lock
, LK_EXCLUSIVE
);
92 simple_lock(&adosfs_hashlock
);
93 LIST_INSERT_HEAD(&
->anodetab
[AHASH(ap
->block
)], ap
, link
);
94 simple_unlock(&adosfs_hashlock
);
98 adosfs_aremhash(struct anode
*ap
)
100 simple_lock(&adosfs_hashlock
);
101 LIST_REMOVE(ap
, link
);
102 simple_unlock(&adosfs_hashlock
);
106 adosfs_getblktype(struct adosfsmount
*amp
, struct buf
*bp
)
108 if (adoscksum(bp
, amp
->nwords
)) {
110 printf("adosfs: aget: cksum of blk %" PRId64
" failed\n",
111 bp
->b_blkno
/ (amp
->bsize
/ DEV_BSIZE
));
117 * check primary block type
119 if (adoswordn(bp
, 0) != BPT_SHORT
) {
121 printf("adosfs: aget: bad primary type blk %" PRId64
" (type = %d)\n",
122 bp
->b_blkno
/ (amp
->bsize
/ DEV_BSIZE
), adoswordn(bp
,0));
128 * Check secondary block type.
130 switch (adoswordn(bp
, amp
->nwords
- 1)) {
131 case BST_RDIR
: /* root block */
133 case BST_LDIR
: /* hard link to dir */
135 case BST_UDIR
: /* user dir */
137 case BST_LFILE
: /* hard link to file */
139 case BST_FILE
: /* file header */
141 case BST_SLINK
: /* soft link */
146 printf("adosfs: aget: bad secondary type blk %" PRId64
" (type = %d)\n",
147 bp
->b_blkno
/ (amp
->bsize
/ DEV_BSIZE
), adoswordn(bp
, amp
->nwords
- 1));
154 adunixprot(int adprot
)
156 if (adprot
& 0xc000ee00) {
157 adprot
= (adprot
& 0xee0e) >> 1;
158 return (((adprot
& 0x7) << 6) |
159 ((adprot
& 0x700) >> 5) |
160 ((adprot
& 0x7000) >> 12));
163 adprot
= (adprot
>> 1) & 0x7;
164 return((adprot
<< 6) | (adprot
<< 3) | adprot
);
169 CapitalChar(int ch
, int inter
)
171 if ((ch
>= 'a' && ch
<= 'z') ||
172 (inter
&& ch
>= 0xe0 && ch
<= 0xfe && ch
!= 0xf7))
173 return(ch
- ('a' - 'A'));
178 adoscksum(struct buf
*bp
, int n
)
182 lp
= (u_int32_t
*)bp
->b_data
;
191 adoscaseequ(const u_char
*name1
, const u_char
*name2
, int len
, int inter
)
194 if (CapitalChar(*name1
++, inter
) !=
195 CapitalChar(*name2
++, inter
))
202 adoshash(const u_char
*nam
, int namlen
, int nelt
, int inter
)
208 val
= ((val
* 13) + CapitalChar(*nam
++, inter
)) & 0x7ff;
214 * datestamp is local time, tv is to be UTC
217 dstotv(struct datestamp
*dsp
, struct timeval
*tvp
)
222 * tv is UTC, datestamp is to be local time
225 tvtods(struct timeval
*tvp
, struct datestamp
*dsp
)
230 #if BYTE_ORDER != BIG_ENDIAN
232 adoswordn(struct buf
*bp
, int wn
)
235 * ados stored in network (big endian) order
237 return(ntohl(*((u_int32_t
*)bp
->b_data
+ wn
)));