Final Exam. May 8, 2001. Question 4 -- Answers and Grading

15 points total

Answer

Part 1

The metadata looks quite a bit like a Unix inode, but with a subtle change. It is 16 words long. The first word has the size of the file:
  if (offset > file[0]) { flag error }
The next 13 words are pointers to the first thirteen blocks of the file:
  if (bn < 13) {
    get_block(buf, file[bn+1]);
    return buf[bo];
  }
The 14th word is a pointer to a block of cached block pointers. It contains pairs of file block numbers and disk pointers. So if a block number is thirteen or greater, before we try to find it elsewhere, we check the cache:
  get_block(buf,file[14]);
  ip = (int *) buf;
  for (i = 0; i < ibs; i += 2) {
    if (ip[i] == bn) {
      get_block(buf, ip[i+1]);
      return buf[bo];
    }
  }
Finally, the last block is a pointer to a triple indirect block, as described in section 11.2.3 of the book (indexed allocation). That block contains pointers to blocks (level 1). The blocks pointed to by level 1 pointers contain pointers to blocks (level 2). And the The blocks pointed to by level 2 pointers contain pointers to blocks (level 3). These pointers point to file blocks.

  bn -= 13;
  
  ib1n = bn / ibs;
  ib1o = bn % ibs;
  ib2n = ib1n / ibs;
  ib2o = ib1n % ibs;

  get_block(buf, file[15]);
  get_block(buf, buf[ib2n]);
  get_block(buf, buf[ib2o]);
  get_block(buf, buf[ib1o]);
  return buf[bo];
So, for example, to get block 13, you have get the block in file[15]
to get the first level 1 pointer.  Use that to get the level 1 block, 
and the first level 2 pointer.  Use that to get the level 2 block, 
and the first level 3 pointer.  Use that to get the level 3 block,
and the pointer to file block 13.  

Now, motivationally, this structure works well for small files, but holds arbitrarily big files too. If we cache recently-used blocks (or perhaps cache based on lookahead) in our disk-reading routines, then we can use the cache block to improve performance when getting blocks greater than number 12.

Part 2

The first 13 pointers are responsible for 128 bytes each, and the last pointer is responsible for 32*32*32*128 = 2^22 bytes (roughly 4 megabytes). The whole expression is:

(13 * 128) + (32 * 32 * 32 * 128) = 4,195,968 bytes

Grading

Only one student got the fact that file[14] was meant to be a cache -- well done!