2009-12-20 21:41:50 +01:00
|
|
|
/* This file manages the super block table and the related data structures,
|
|
|
|
* namely, the bit maps that keep track of which zones and which inodes are
|
|
|
|
* allocated and which are free. When a new inode or zone is needed, the
|
|
|
|
* appropriate bit map is searched for a free entry.
|
|
|
|
*
|
|
|
|
* The entry points into this file are
|
|
|
|
* alloc_bit: somebody wants to allocate a zone or inode; find one
|
|
|
|
* free_bit: indicate that a zone or inode is available for allocation
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "fs.h"
|
|
|
|
#include "buf.h"
|
|
|
|
#include "inode.h"
|
|
|
|
#include "const.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* alloc_bit *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
bit_t alloc_bit(void)
|
2009-12-20 21:41:50 +01:00
|
|
|
{
|
|
|
|
/* Allocate a bit from a bit map and return its bit number. */
|
2012-02-13 16:28:04 +01:00
|
|
|
bitchunk_t *wptr, *wlim;
|
2009-12-20 21:41:50 +01:00
|
|
|
bit_t b;
|
2010-05-28 11:39:18 +02:00
|
|
|
unsigned int i, bcount;
|
2009-12-20 21:41:50 +01:00
|
|
|
|
|
|
|
bcount = FS_BITMAP_CHUNKS(NR_INODES); /* Inode map has this many chunks. */
|
|
|
|
wlim = &inodemap[bcount]; /* Point to last chunk in inodemap. */
|
|
|
|
|
|
|
|
for (wptr = &inodemap[0]; wptr < wlim; wptr++) {
|
2012-02-13 16:28:04 +01:00
|
|
|
/* Does this word contain a free bit? */
|
|
|
|
if (*wptr == (bitchunk_t) ~0) continue; /* No. Go to next word */
|
2009-12-20 21:41:50 +01:00
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
/* Find and allocate the free bit. */
|
|
|
|
for (i = 0; (*wptr & (1 << i)) != 0; ++i) {}
|
2009-12-20 21:41:50 +01:00
|
|
|
|
|
|
|
/* Get inode number */
|
2012-02-13 16:28:04 +01:00
|
|
|
b = (bit_t) ((wptr - &inodemap[0]) * FS_BITCHUNK_BITS + i);
|
2009-12-20 21:41:50 +01:00
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
/* Don't allocate bits beyond end of map. */
|
|
|
|
if (b >= NR_INODES) break;
|
|
|
|
|
|
|
|
/* Allocate and return bit number. */
|
|
|
|
*wptr |= 1 << i;
|
2009-12-20 21:41:50 +01:00
|
|
|
|
|
|
|
/* Mark server 'busy' */
|
|
|
|
busy++;
|
2012-02-13 16:28:04 +01:00
|
|
|
return(b);
|
2009-12-20 21:41:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return(NO_BIT); /* no bit could be allocated */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* free_bit *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
void free_bit(bit_returned)
|
2009-12-20 21:41:50 +01:00
|
|
|
bit_t bit_returned; /* number of bit to insert into the inode map*/
|
|
|
|
{
|
|
|
|
bitchunk_t *k, mask;
|
|
|
|
bit_t bit;
|
|
|
|
unsigned word;
|
|
|
|
|
|
|
|
/* Get word offset and bit within offset */
|
2010-05-28 11:39:18 +02:00
|
|
|
word = (unsigned) (bit_returned / (bit_t) FS_BITCHUNK_BITS);
|
|
|
|
bit = bit_returned % (bit_t) FS_BITCHUNK_BITS;
|
2009-12-20 21:41:50 +01:00
|
|
|
|
|
|
|
/* Unset bit */
|
|
|
|
k = &inodemap[word];
|
2010-05-28 11:39:18 +02:00
|
|
|
mask = (unsigned) 1 << bit;
|
2009-12-20 21:41:50 +01:00
|
|
|
*k &= ~mask;
|
|
|
|
|
|
|
|
busy--; /* One inode less in use. */
|
|
|
|
}
|