In XINU, an index block is smaller than a disk block. Thus, more than one (in fact - 8) index block is contained in each disk block. Each index block contains the following entries:
Because 8 index blocks are contained in a disk block, there is a macro
which given an index block number, translates it to a disk block address.
This macro is:
#define ibtodb(ib) (((ib)>>3)+IBAREA)
First, this divides the index block number by eight (as there are
8 index blocks per disk block) and then adds IBAREA to the result. IBAREA
is the first disk block of the disk's index area. Because the directory
lives in block 0 and is one block long, the value for IBAREA is 1.
Reading and writing index blocks is fairly straight-forward. To read an index block, first we calculate which disk block it lives in, then we read that disk block, and copy the desired index block into the provided buffer. The routine to do this is called ibget().
Writing an index block is similar. First, we wait on a semaphore that protects writes to the index blocks (only one process can write an index block at a time). Then the entire disk block containing the index block we want to write is read in. Then the index block is written over the read disk block at the correct offset within the buffer. Finally, the entire disk block (with the modified index block) is written back to disk. Remember that we have to read and write an entire disk block (rather than just the desired index block) because the smallest addressable unit of disk I/O is the disk block.
There are also a pair of routines to allocate a single index block, and to free a list of index blocks. Free index blocks are kept on a list pointed to by an entry in the directory.