/* * place the specified disk block * back on the free list of the * specified device. */ void free(dev_t dev, daddr_t bno) { struct filsys *fp; struct buf *bp; if (debugFree) { printf("----- free dev = 0x%08X, bno = 0x%08X -----\n", dev, bno); } fp = getfs(dev); fp->s_fmod = 1; while(fp->s_flock) sleep((caddr_t)&fp->s_flock, PINOD); if (badblock(fp, bno, dev)) return; if(fp->s_nfree <= 0) { fp->s_nfree = 1; fp->s_free[0] = 0; } if(fp->s_nfree >= NICFREE) { fp->s_flock++; bp = getblk(dev, bno); ((FBLKP)(bp->b_un.b_addr))->df_nfree = fp->s_nfree; bcopy((caddr_t)fp->s_free, (caddr_t)((FBLKP)(bp->b_un.b_addr))->df_free, sizeof(fp->s_free)); fp->s_nfree = 0; bwrite(bp); fp->s_flock = 0; wakeup((caddr_t)&fp->s_flock); } fp->s_free[fp->s_nfree++] = bno; fp->s_fmod = 1; }
/* * place the specified disk block * back on the free list of the * specified device. */ free(dev, bno) { register *fp, *bp, *ip; fp = getfs(dev); fp->s_fmod = 1; while(fp->s_flock) sleep(&fp->s_flock, PINOD); if (badblock(fp, bno, dev)) return; if(fp->s_nfree <= 0) { fp->s_nfree = 1; fp->s_free[0] = 0; } if(fp->s_nfree >= 100) { fp->s_flock++; bp = getblk(dev, bno); ip = bp->b_addr; *ip++ = fp->s_nfree; bcopy(fp->s_free, ip, 100); fp->s_nfree = 0; bwrite(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } fp->s_free[fp->s_nfree++] = bno; fp->s_fmod = 1; }
/* * alloc will obtain the next available * free disk block from the free list of * the specified device. * The super block has up to NICFREE remembered * free blocks; the last of these is read to * obtain NICFREE more . . . * * no space on dev x/y -- when * the free list is exhausted. */ struct buf *alloc(dev_t dev) { daddr_t bno; struct filsys *fp; struct buf *bp; if (debugAlloc) { printf("----- alloc dev = 0x%08X -----\n", dev); } fp = getfs(dev); while(fp->s_flock) sleep((caddr_t)&fp->s_flock, PINOD); do { if(fp->s_nfree <= 0) goto nospace; if (fp->s_nfree > NICFREE) { prdev("bad free count", dev); goto nospace; } bno = fp->s_free[--fp->s_nfree]; if(bno == 0) goto nospace; } while (badblock(fp, bno, dev)); if(fp->s_nfree <= 0) { fp->s_flock++; bp = bread(dev, bno); if ((bp->b_flags&B_ERROR) == 0) { fp->s_nfree = ((FBLKP)(bp->b_un.b_addr))->df_nfree; bcopy((caddr_t)((FBLKP)(bp->b_un.b_addr))->df_free, (caddr_t)fp->s_free, sizeof(fp->s_free)); } brelse(bp); fp->s_flock = 0; wakeup((caddr_t)&fp->s_flock); if (fp->s_nfree <=0) goto nospace; } bp = getblk(dev, bno); clrbuf(bp); fp->s_fmod = 1; if (debugAlloc) { printf(" alloc = 0x%08X\n", bp->b_blkno); } return(bp); nospace: fp->s_nfree = 0; prdev("no space", dev); u.u_error = ENOSPC; return(NULL); }