Final Year Project: Using Linux Filesystems Under Windows   Chris Bryden BEng. Electronics and Software Engineering    School of Computer Science   University of Birmingham 43 longs)  is  used  to  keep  track  of  the  next  position  in  the  memory  buffer  to  read block addresses into.   Each time a block is read into the buffer ulBuffOffset is  incremented  by  ulLongPerBlk.  This  variable  stores  the  number  of  unsigned longs that a block contains.   The  addresses  of  the  direct  blocks  are  simply  read  from  the  first  12 elements  of  the  ‘blocks’  array  contained  in  the  inode.  (For  details  of  the  inode structure please see section 3.3.5).   The next element of the array (element 12) gives the block address of the indirect  blocks.  This  is  a  block  of  block  addresses  of    allocated  blocks.  See section  3.3.5  for  more  information  on  how  the  inode  stores  allocated  block addresses  .  These  block  addresses  are  read  into the memory buffer using the ReadBlock function.   Element  13  of  the  array  gives  the  block  address  of  the  block  of  double indirect   blocks.   This   block   contains  pointers  to  blocks  containing  the  block addresses  of  the  actual  allocated  blocks.  This  block  is  read  and  buffered  in  a separate memory buffer, lpBuff. Each block of direct blocks that the elements in lpBuff  hold  the  block  addresses  of  is  then  read  into  the  lpBlocksBuff  memory buffer. This operation is performed by the code section below: Element  14  of  the  array  gives  the  block  address  of  the  block  of  triple indirect   blocks.   This   works   in   a   similar   way   to   the   double   indirect   blocks described above, except with another layer of indirection. This block is buffered in a buffer pointed to by lpTripBuff. Each element of this buffer points to a block of  double  indirect  blocks.  Each  of  these  blocks  of  double  indirect  blocks  is processed as described for double indirect blocks, above. Once the complete list of block addresses has been read into the memory buffer pointed to by lpBlocksBuff, this pointer is returned to the calling function. //buffer up block of indirect blocks if(!ReadBlock(bDrive, bPart, Inode.i_block[13], lpBuff)) {farfree(lpBuff); return NULL;} while((lpBuff[iBlk] != 0) && (iBlk <= ulLongPerBlk)) { //expand memory buffer lpTemp = farrealloc(lpBlocksBuff, (ulBuffOffset * uLongSize) + ulBlkSize); if (lpTemp != NULL) lpBlocksBuff = lpTemp; else {farfree(lpBuff); return NULL;} //read direct blocks ReadBlock(bDrive, bPart, lpBuff[iBlk], lpBlocksBuff + ulBuffOffset); ++iBlk; ulBuffOffset += ulLongPerBlk; }