Commit | Line | Data |
---|---|---|
261cc9f3 KT |
1 | # |
2 | /* | |
3 | * Copyright 1973 Bell Telephone Laboratories Inc | |
4 | */ | |
5 | ||
6 | #include "../param.h" | |
7 | #include "../systm.h" | |
8 | #include "../filsys.h" | |
9 | #include "../buf.h" | |
10 | #include "../inode.h" | |
11 | #include "../user.h" | |
12 | ||
13 | iinit() | |
14 | { | |
15 | register *cp, *bp; | |
16 | ||
17 | bp = bread(rootdev, 1); | |
18 | cp = getblk(NODEV); | |
19 | if(u.u_error) | |
20 | panic("iinit"); | |
21 | bcopy(bp->b_addr, cp->b_addr, 256); | |
22 | brelse(bp); | |
23 | mount[0].m_bufp = cp; | |
24 | mount[0].m_dev = rootdev; | |
25 | cp = cp->b_addr; | |
26 | cp->s_flock = 0; | |
27 | cp->s_ilock = 0; | |
28 | cp->s_ronly = 0; | |
29 | time[0] = cp->s_time[0]; | |
30 | time[1] = cp->s_time[1]; | |
31 | } | |
32 | ||
33 | alloc(dev) | |
34 | { | |
35 | int bno; | |
36 | register *bp, *ip, *fp; | |
37 | ||
38 | fp = getfs(dev); | |
39 | while(fp->s_flock) | |
40 | sleep(&fp->s_flock, PINOD); | |
41 | do { | |
42 | bno = fp->s_free[--fp->s_nfree]; | |
43 | if(bno == 0) { | |
44 | fp->s_nfree++; | |
45 | prdev("no space", dev); | |
46 | u.u_error = ENOSPC; | |
47 | return(NULL); | |
48 | } | |
49 | } while (badblock(fp, bno, dev)); | |
50 | if(fp->s_nfree <= 0) { | |
51 | fp->s_flock++; | |
52 | bp = bread(dev, bno); | |
53 | ip = bp->b_addr; | |
54 | fp->s_nfree = *ip++; | |
55 | bcopy(ip, fp->s_free, 100); | |
56 | brelse(bp); | |
57 | fp->s_flock = 0; | |
58 | wakeup(&fp->s_flock); | |
59 | } | |
60 | bp = getblk(dev, bno); | |
61 | clrbuf(bp); | |
62 | fp->s_fmod = 1; | |
63 | return(bp); | |
64 | } | |
65 | ||
66 | free(dev, bno) | |
67 | { | |
68 | register *fp, *bp, *ip; | |
69 | ||
70 | fp = getfs(dev); | |
71 | fp->s_fmod = 1; | |
72 | while(fp->s_flock) | |
73 | sleep(&fp->s_flock, PINOD); | |
74 | if (badblock(fp, bno, dev)) | |
75 | return; | |
76 | if(fp->s_nfree >= 100) { | |
77 | fp->s_flock++; | |
78 | bp = getblk(dev, bno); | |
79 | ip = bp->b_addr; | |
80 | *ip++ = fp->s_nfree; | |
81 | bcopy(fp->s_free, ip, 100); | |
82 | fp->s_nfree = 0; | |
83 | bwrite(bp); | |
84 | fp->s_flock = 0; | |
85 | wakeup(&fp->s_flock); | |
86 | } | |
87 | fp->s_free[fp->s_nfree++] = bno; | |
88 | fp->s_fmod = 1; | |
89 | } | |
90 | ||
91 | badblock(afp, abn, dev) | |
92 | { | |
93 | register struct filsys *fp; | |
94 | register char *bn; | |
95 | ||
96 | fp = afp; | |
97 | bn = abn; | |
98 | if (bn < fp->s_isize+2 || bn >= fp->s_fsize) { | |
99 | prdev("bad block", dev); | |
100 | return(1); | |
101 | } | |
102 | return(0); | |
103 | } | |
104 | ||
105 | ialloc(dev) | |
106 | { | |
107 | register *fp, *bp, *ip; | |
108 | int i, j, k, ino; | |
109 | ||
110 | fp = getfs(dev); | |
111 | while(fp->s_ilock) | |
112 | sleep(&fp->s_ilock, PINOD); | |
113 | loop: | |
114 | if(fp->s_ninode > 0) { | |
115 | ino = fp->s_inode[--fp->s_ninode]; | |
116 | ip = iget(dev, ino); | |
117 | if(ip->i_mode == 0) { | |
118 | for(bp = &ip->i_mode; bp < &ip->i_addr[8];) | |
119 | *bp++ = 0; | |
120 | fp->s_fmod = 1; | |
121 | return(ip); | |
122 | } | |
123 | printf("busy i\n"); | |
124 | iput(ip); | |
125 | goto loop; | |
126 | } | |
127 | fp->s_ilock++; | |
128 | ino = 0; | |
129 | for(i=0; i<fp->s_isize; i++) { | |
130 | bp = bread(dev, i+2); | |
131 | ip = bp->b_addr; | |
132 | for(j=0; j<256; j=+16) { | |
133 | ino++; | |
134 | if(ip[j] != 0) | |
135 | continue; | |
136 | for(k=0; k<NINODE; k++) | |
137 | if(dev==inode[k].i_dev && ino==inode[k].i_number) | |
138 | goto cont; | |
139 | fp->s_inode[fp->s_ninode++] = ino; | |
140 | if(fp->s_ninode >= 100) | |
141 | break; | |
142 | cont:; | |
143 | } | |
144 | brelse(bp); | |
145 | if(fp->s_ninode >= 100) | |
146 | break; | |
147 | } | |
148 | if(fp->s_ninode <= 0) | |
149 | panic("out of inodes"); | |
150 | fp->s_ilock = 0; | |
151 | wakeup(&fp->s_ilock); | |
152 | goto loop; | |
153 | } | |
154 | ||
155 | ifree(dev, ino) | |
156 | { | |
157 | register *fp; | |
158 | ||
159 | fp = getfs(dev); | |
160 | if(fp->s_ilock) | |
161 | return; | |
162 | if(fp->s_ninode >= 100) | |
163 | return; | |
164 | fp->s_inode[fp->s_ninode++] = ino; | |
165 | fp->s_fmod = 1; | |
166 | } | |
167 | ||
168 | getfs(dev) | |
169 | { | |
170 | register struct mount *p; | |
171 | register char *n1, *n2; | |
172 | ||
173 | for(p = &mount[0]; p < &mount[NMOUNT]; p++) | |
174 | if(p->m_bufp != NULL && p->m_dev == dev) { | |
175 | p = p->m_bufp->b_addr; | |
176 | n1 = p->s_nfree; | |
177 | n2 = p->s_ninode; | |
178 | if(n1 > 100 || n2 > 100) { | |
179 | prdev("bad count", dev); | |
180 | p->s_nfree = 0; | |
181 | p->s_free[0] = 0; | |
182 | p->s_ninode = 0; | |
183 | p->s_inode[0] = 0; | |
184 | } | |
185 | return(p); | |
186 | } | |
187 | panic("no fs"); | |
188 | } | |
189 | ||
190 | update() | |
191 | { | |
192 | register struct inode *ip; | |
193 | register struct mount *mp; | |
194 | register *bp; | |
195 | ||
196 | if(updlock) | |
197 | return; | |
198 | updlock++; | |
199 | for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) | |
200 | if(mp->m_bufp != NULL) { | |
201 | ip = mp->m_bufp->b_addr; | |
202 | if(ip->s_fmod==0 || ip->s_ilock!=0 || | |
203 | ip->s_flock!=0 || ip->s_ronly!=0) | |
204 | continue; | |
205 | bp = getblk(mp->m_dev, 1); | |
206 | ip->s_fmod = 0; | |
207 | ip->s_time[0] = time[0]; | |
208 | ip->s_time[1] = time[1]; | |
209 | bcopy(ip, bp->b_addr, 256); | |
210 | bwrite(bp); | |
211 | } | |
212 | for(ip = &inode[0]; ip < &inode[NINODE]; ip++) | |
213 | if((ip->i_flag&ILOCK) == 0) { | |
214 | ip->i_flag =| ILOCK; | |
215 | iupdat(ip, time); | |
216 | prele(ip); | |
217 | } | |
218 | updlock = 0; | |
219 | bflush(NODEV); | |
220 | } |