CEG 433/633: Operating Systems

Solution to an Exam Problem
Prabhaker Mateti

Problem Statement

Consider a file volume based on i-nodes on a hard disk drive. Our disk has the following parameters: 2^32 cylinders, 2^8 heads, 2^16 sectors per track, and 2^20 bytes per sector. Immediately after creating the empty file volume, we intend to store files named small0 through small7 of size 64 MB each, medium0 through medium7 of size 2 GB. Some number of large and huge files will also need to be stored eventually. Design a file volume to accommodate the above. In all the answers you give, defend why you consider them reasonable. Use ellipsis (...) where obvious.

[ These files are not all that the disk will ever have. Files will be added and deleted as time goes on, and our design should hold good for its intended purpose (which is not fully clear from the above description) without having to re-make the volume.]

[An exam question may simplify the above to specifics such as the ones shown below. ]

  1. What is a good range (min to max) for block size?
  2. What is a good range for the i-node height?
  3. What is the size of the largest file that can be stored using triple-indirection?
  4. Show the contents of the following:
    1. the contents of i-nodes (including indirect blocks, if any) numbered 1, 4, 16, and 32,
    2. the root directory contents, as a conceptual table of name + i-numbers,
    3. the sequential listing of all the block numbers of file medium6

Solution

[There is some meta-discussion of this type, enclosed in brackets, only once in a while assuming that you have attended the lectures where the design was discussed at length.]

[This is a rather detailed answer -- far more detailed than can be expected in an exam. Many of you have received full score for much less than the kind of answer shown below. To help you relate to P2, I have used the data member names from fs33types.h. ]

[By the way, even though this is a very complete answer, this is not a perfect design. ]

[Recall that 1 M = 1 K * 1 K = 2^10 * 2^10 = 2^20, 1 G = 1 K * 1 M = 2^30. In CS/CEG, 1 M does not stand for 10^6. ]

The File Volume Layout =

Super Block,
Free Bit Vector of Blocks,
Free Bit Vector of iNodes,
iNode Array,
File Content And Indirect Blocks.
[To help you understand better, I am using symbolic names; in the exam, you must provide actual numbers (perhaps as powers of 2.]

Let us use nsb, nfbvb, nfbvi, niab, nfc as the sizes of these components in units of blocks. We assume nsb == 1.

[Recall that a file is labeled a (i) small, (ii) medium, (iii) large, (iv) huge file depending on whether its inode has (i) no indirect blocks, (ii) has only a single-indirect block, (iii) has a double indirect block, (iv) triple indirect block. If need be we can also have a quadruple indirect block; this usually implies too small a block size.  The names of files used in the problem statement are suggestive of this labeling. ]


Block-Size, iNode Width and iNode Height

The choices of block-size, inode width and inode height are interdependent.

If we let block-size = sector-size, then the inode as required by small files is way too high.  This will make an inode bigger than such a block.

[An inode should never be bigger than a block. Selected inodes are cached in main memory; so, they should also be as small as possible.]

Suppose we choose a block size of 8 MB.

Our small files are 64 MB. Small files should only use direct entries.  Since we were not given how big a small file can be we take 64 MB as near the high range but not the max MB. Suppose, we have 16 total entries in an inode. Subtracting the file size, inode-type, single-, double-, triple-indirects, we have 11 direct entries.

The largest small file == 11*8 == 88 MB.

Our small file of 64 MB fits comfortably in an inode of height 16. Good.

uint iHeight = 16;

[An integral number of inodes should fit in one block. Also, we do not want an inode to straddle block boundaries.]

We won't go for a height of 32 because we assumed 64 MB to be near the high range of small files.  A height of 8 will require single-indirect block even for our small files.

Block size of 4 MB would reduce internal fragmentation, but would increase the iHeight. 16 MB would increase internal fragmentation. Since we were not given the distribution of the small files, we cannot decide among reasonable choices of 4, 8, 16, 32, ... MB for block size. So, we stay with 8 MB.

Total number of disk blocks

= total number of bytes in the disk / block-size
= (2^32 * 2^8 * 2^16 * 2^20) / (8*2^20)
= 2^(32 + 8 + 16 + 20 - 3 - 20)
= 2^53

The blocks are numbered 0 .. 2^53-1. uint maxLogicalBlockNumber = 2^53-1.

An inode should be wide enough to store the maxLogicalBlockNumber.  So, the 4 bytes (== sizeof(uint)) will not do.  We need 7 bytes, but we choose i Width = 8 bytes for programming ease.


Free Bit Vector of Blocks

nfbvb =
= (number of blocks), in bits
= 2^53, in bits
= 2^53 / 8, in bytes
= 2^53 / (8 * blockSize), in blocks
= 2^53 / (8 * 8 * 2^20), in blocks
= 2^(53 - 3 - 3 - 20), in blocks
= 2^27 blocks


Free Bit Vector of iNodes

No data regarding the distribution of small, medium, etc. is given. So, we estimate the number of inodes based on small files, which errs on having too many.

uint iHeight = 16; // see above
uint iWidth = 8; // see above

uint nInodes

= i-nodes needed
= disk size / small-file-size
= (2^53 * 8 * 2^20) / (64 * 2^20) = 2^50;

uint nfbvi

= 2^50, in bits
= 2^50 / 8 in bytes
= 2^50 / (8 * blockSize), in blocks
= 2^(50 - 3 - 3 - 20), in blocks
= 2^24 in blocks


iNode Array

niab
= Space occupied by the iNode array
= nInodes * (space for one inode)
= 2^50 * (iwidth * iheight) in bytes
= 2^50 * (8 * 16) in bytes
= 2^57 in bytes
= 2^(57 - 3 - 20) in blocks
= 2^34 in blocks


Root Directory

The root dir content begins at block numbered rbn

= nsb + nfbvb + nfbvi + niab.
= 1 + 2^27 + 2^24 + 2^34
[You can leave this in this unsimplified but numerical form]

Let us allow for a directory entry of name + i number to be at most one block. This gives a max file name length of (8*2^20 - 8) bytes.

File Content And Indirect Blocks has at its beginning the root dir content. The i-number of the root is 1. [We have an inode#0, but it is left unused for simplicity. ]

As a table of two columns, the root directory has:
. 1
.. 1
small0 2
... ...
small7 9
medium0 10
... ...
medium7 17

Size, in bytes, of root directory

= 1+1+8 for dot,
+ 2+1+8 for dot-dot,
+ 6+1+8 for small0,
+ (6+1+8)*7 for ..., small7,
+ 7+1+8 for medium0,
+ (7+1+8)*7 for ..., medium7 entries.

[Saving time during the exam, but accurately guessing that the above takes less than one block, we move on.]


Small Files

File named small0 begins at block number, bnfs0 = rbn + 1.
It occupies 64/8 == 8 blocks, numbered rbn + 1, ..., rbn + 8.

...

File named small7 begins at block number, bnfs7 = rbn + 1 + 7*8.
It occupies 64/8 == 8 blocks, numbered rbn + 1 + 7*8, ..., rbn + 8 + 7*8.


Indirect Blocks

A single indirect block can store this many block numbers
= blockSize / iWidth
= 8*2^20 / 8
= 2^20
Thus, the max file size of a so-called medium file
= 11 + 2^20 blocks
= (11 + 2^20) * 8 MB
= 11 * 8 MB + 2^10 * 8 GB
> 8*2^10 GB

This is way more than what we need for the given medium files.

The max file size of a so-called large file = 11 + 2^20 + (2^20)^2 blocks

The max file size of a so-called huge file = 11 + 2^20 + (2^20)^2 + (2^20)^3 blocks


Medium Files

File named medium0 begins at block number, bnfm0 = rbn + 1 + 8*8. It occupies 2 GB / 8MB = 2*2^10 MB / 8 MB =  2^8 = 256 blocks, numbered bnfm0, ..., bnfm0+10, bnfm0+12, bnfm0+13, ..., bnfm0 + 256. Note the skip at bnfm0+11. This block is the single indirect block for this file.  It contains the numbers   bnfm0+12, bnfm0+13, ..., bnfm0 + 256, the rest being 0.

...

File named medium7 begins at block number, bnfm7 = bnfm0 + 7*256. It occupies 256 blocks, numbered bnfm7, ...,bnfm7+10, bnfm7+12, ...,  bnfm7 + 256.  The block numbered bnfm7+11 is the single indirect block for this file.  It contains the numbers   bnfm7+12, bnfm7+13, ..., bnfm7 + 256, the rest being 0.


Specific Inodes

inode 0 is unused.
inode 1 stores the info of root. Its contents are:

 
0 rbn
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 directoryTp
15 szrootdir

 

inode 4 stores the info of small2. Its contents are:

 
0 rbn+17
1 rbn+18
2 rbn+19
3 rbn+20
4 rbn+21
5 rbn+22
6 rbn+23
7 rbn+24
8 0
9 0
10 0
11 0
12 0
13 0
14 ordinaryTp
15 64*2^20

 

inode 16 stores the info of medium6. Its contents are:

 
0 bnfm6
1 bnfm6+1
2 bnfm6+2
3 bnfm6+3
4 bnfm6+4
5 bnfm6+5
6 bnfm6+6
7 bnfm6+7
8 bnfm6+8
9 bnfm6+9
10 bnfm6+10
11 bnfm6+11
12 0
13 0
14 ordinaryTp
15 2*2^30

bnfm6 + 11 is a single indirect block. Its contents are: bnfm6 + 12, bnfm6 + 13, ..., bnfm6 + 256, the rest being 0.

inode 32 exists but is unused. Its content is all-zero.

 
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 0
15 0


 
Copyright © 2007 mailto:pmateti@wright.edu?subject=CEG433:OperatingSystems February 12, 2007