Research V5 development
[unix-history] / usr / sys / ken / alloc.c
CommitLineData
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
13iinit()
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
33alloc(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
66free(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
91badblock(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
105ialloc(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);
113loop:
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
155ifree(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
168getfs(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
190update()
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}