LAB Assignment #5

 ******************** DUE: Thursday, 3-23-2023 **********************

 Given: diskimage is a virtual disk containing an EXT2 File System.
 Write a C program, showblock, which displays the disk blocks of a file 
 in an EXT2 file system. The program runs as follows

       showblock  pathname
       ---------  -----------
e.g.   showblock  /a/b/c/d       
OR     showblock              input a pathname, e.g. /a/b/c/d
 
 It finds the pathname file and prints its disk block numbers
 (direct, indirect, double-indirect) of the file.
********************************************************************/ 
                   HELP INFO:

#include <ext2fs/ext2_fs.h>

typedef struct ext2_super_block SUPER;
typedef struct ext2_group_desc  GD;
typedef struct ext2_inode       INODE;
typedef struct ext2_dir_entry_2 DIR;


1. HOW TO Traverse EXT2 File System Tree: Chapter 11.5

   Given a disk, diskimage, containing an ext2 FS, and a pathname, e.g.
                 /cs360/is/fun
   find the file.

   NOTE !!! Finding a file is to find its INODE. 
            From the file's INODE, you have ALL the information of the file.
  
2. ALGORITHM:

(1). Under Linux: Open diskimage for READ: Use file descriptor as dev number.

          #include <fcntl.h>
          #define BLKSIZE 1024
 
          char *disk = "diskimage";
          int dev = open(disk, O_RDONLY);   // OR  O_RDWR

          // get_block() reads a disk BLOCK into a char buf[BLKSIZE].
   
          int get_block(int dev, int blk, char buf[ ])
          {   
              lseek(dev, blk*BLKSIZE, SEEK_SET);
              return read(dev, buf, BLKSIZE);
          }
 
FOR BLKSIZE=1KB: SUPER block=1; groupDescriptor block=2 

(2). Read in SUPER block (block #1) to verify diskimage is an EXT2 FS
 
(3). Read in Group Descriptor 0 (in block #2) to get block number of 
     bmap, imap, inodes_start;  Print their values.

(4). mount root: Let INODE *root point at root INODE (ino=2) in memory:
   
(5). The following C code prints the entries of a DIRectory INODE:

int show_dir(INODE *ip)
{
   char sbuf[BLKSIZE], temp[256];
   DIR *dp;
   char *cp;
 
   // ASSUME only one data block i_block[0]
   // YOU SHOULD print i_block[0] number to see its value
   get_block(dev, ip->i_block[0], sbuf);

   dp = (DIR *)sbuf;
   cp = sbuf;
 
   while(cp < sbuf + BLKSIZE){
       strncpy(temp, dp->name, dp->name_len);
       temp[dp->name_len] = 0;  // convert dp->name into a string
      
       printf("%4d %4d %4d %s\n", dp->inode, dp->rec_len, dp->name_len, temp);

       cp += dp->rec_len;      // advance cp by rec_len
       dp = (DIR *)cp;         // pull dp to cp
   }
}

(5).1: Print contents of the root DIRectory (ino=2)

(5).2: Modify show_dir() to wrtie a search() function

          int search(INODE *ip, char *name)
  
   which searches the DIR's data block for a name string; 
   return its inode number if found; return 0 if not.

(6). Tokenize pathname into name[0], name[1],... name[n-1]

(7). Start from the root inode #2: 

     INODE *ip = root;
     char buf[BLKSIZE];
     int  ino, blk, offset;

     for (int i=0; i < n; i++){
         ino = search(ip, name[i]);
        
         if (ino==0){
            printf("can't find %s\n", name[i]); 
            exit(1);
         }
  
         // Use Mailman's algorithm to Convert (dev, ino) to newINODE pointer
    
         ip points at newINODE of (dev, ino);
     }
  
(8). When the above loop ends, ip MUST point at the INODE of pathname.

(9). Extract information from ip-> as needed:

       Print direct block numbers;
       Print indirect block numbers; 
       Print double indirect block numbers, if any

     Pat yourself on the back and say: Good Job!

===============================================================================
SAMPLES SOLUTION in samples/LAB5/:

        diskimage: virtual disk with DIRs and FILES
        showdisk : a sh script to display diskimage contents
        lab6.bin : run as  lab5.bin PATHNAME 

                  REVIEW QUESTIONS:

1. Given the INODE of a DIRectory, 
   Write C code to print all names under this DIR:


2. Given the INODE of a file,
   Write C code to print all the INdirecto block numbers of this file: