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: