8 int icformat(Disk*, ulong);
11 * read in the disk structures, return -1 if the format
15 dinit(Disk *d, int f, int psize, char *expname)
29 perror("dinit: stat");
36 * read first physical block to get logical block size, # of inodes,
37 * and # of allocation blocks
39 if(seek(f, 0, 0) < 0){
40 perror("dinit: seek");
43 if(read(f, buf, sizeof(buf)) != sizeof(buf)){
44 perror("dinit: read");
49 fprint(2, "dinit: bsize 0x%lux<= 0\n", ba->bsize);
52 if((ba->bsize % psize) != 0){
53 fprint(2, "dinit: logical bsize (%lud) not multiple of physical (%ud)\n",
58 d->nb = length/d->bsize;
59 d->b2b = (d->bsize - sizeof(Dahdr))*8;
60 d->nab = (d->nb+d->b2b-1)/d->b2b;
61 d->p2b = d->bsize/sizeof(Dptr);
62 strncpy(d->name, ba->name, sizeof d->name);
64 if (expname != nil && strncmp(d->name, expname, sizeof d->name) != 0) {
65 /* Mismatch with recorded name; fail here to force a format */
66 fprint(2, "cfs: name mismatch\n");
71 * check allocation blocks for consistency
73 if(bcinit(d, f, d->bsize) < 0){
74 fprint(2, "dinit: couldn't init block cache\n");
77 for(i = 0; i < d->nab; i++){
80 perror("dinit: read");
83 ba = (Dalloc*)b->data;
84 if(ba->magic != Amagic){
85 fprint(2, "dinit: bad magic in alloc block %uld\n", i);
88 if(d->bsize != ba->bsize){
89 fprint(2, "dinit: bad bsize in alloc block %uld\n", i);
92 if(d->nab != ba->nab){
93 fprint(2, "dinit: bad nab in alloc block %uld\n", i);
96 if(strncmp(d->name, ba->name, sizeof(d->name))){
97 fprint(2, "dinit: bad name in alloc block %uld\n", i);
105 * format the disk as a cache
108 dformat(Disk *d, int f, char *name, ulong bsize, ulong psize)
117 fprint(2, "formatting disk\n");
120 * calculate basic numbers
125 length = dir->length;
127 if((d->bsize % psize) != 0){
128 fprint(2, "cfs: logical bsize not multiple of physical\n");
131 d->nb = length/d->bsize;
132 d->b2b = (d->bsize - sizeof(Dahdr))*8;
133 d->nab = (d->nb+d->b2b-1)/d->b2b;
134 d->p2b = d->bsize/sizeof(Dptr);
137 * init allocation blocks
139 if(bcinit(d, f, d->bsize) < 0)
141 for(i = 0; i < d->nab; i++){
144 perror("cfs: bcalloc");
147 memset(b->data, 0, d->bsize);
148 ba = (Dalloc*)b->data;
150 ba->bsize = d->bsize;
152 strncpy(ba->name, name, sizeof(ba->name));
157 * allocate allocation blocks
159 for(i = 0; i < d->nab; i++)
160 if(dalloc(d, &dptr) == Notabno){
161 fprint(2, "can't allocate allocation blocks\n");
169 * allocate a block from a bit vector page
171 * a return value of Notabno means no blocks left
174 _balloc(Dalloc *ba, ulong max)
176 int len; /* number of valid words */
177 ulong i; /* bit position in long */
179 ulong v; /* old value of long */
183 * find a word with a 0 bit
185 len = (max+BtoUL-1)/BtoUL;
186 for(p = ba->bits, e = p + len; p < e; p++)
193 * find the first 0 bit
196 for(m = 1, i = 0; i < BtoUL; i++, m <<= 1)
201 * calculate block number
203 i += (p - ba->bits)*BtoUL;
217 * return Notabno if none left
220 dalloc(Disk *d, Dptr *p)
227 for(bno = 0; bno < d->nab; bno++){
229 ba = (Dalloc*)b->data;
230 rv = _balloc(ba, max > d->b2b ? d->b2b : max);
232 rv = bno*d->b2b + rv;
234 p->start = p->end = 0;
248 * allocate a block of pointers
251 dpalloc(Disk *d, Dptr *p)
256 if(dalloc(d, p) == Notabno)
260 * allocate the page and invalidate all the
263 b = bcalloc(d, p->bno);
267 for(ep = sp + d->p2b; sp < ep; sp++){
269 sp->start = sp->end = 0;
276 * mark the page as dirty
286 _bfree(Disk *d, ulong i)
294 * get correct allocation block
302 ba = (Dalloc*)b->data;
308 p = ba->bits + (i/BtoUL);
317 * free a block (or blocks)
320 dfree(Disk *d, Dptr *dp)
338 if((bno & Indbno) == 0)
339 return _bfree(d, bno);
342 * first indirect page
348 * then all the pages it points to
350 * DANGER: this algorithm may fail if there are more
351 * allocation blocks than block buffers
357 for(ep = sp + d->p2b; sp < ep; sp++)