|
CS471/571 - Operating Systems
| Displaying exercises/e6/files/disksb.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "fs.h"
#include <arpa/inet.h>
int lread(int fd, int bpos, void *buf, int size);
char *readfile(int fsfd, struct dinode di, int *size);
/**
* This program dumps the superblock information for a Xv6 filesystem
* and attempts to read and output inode 3 (probably the README) from
* the filesystem image specified on the command line.
*/
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Usage:disksb <image>\n");
return 1;
}
int fsfd = open(argv[1], O_RDWR);
if(fsfd < 0){
perror(argv[1]);
exit(1);
}
struct superblock sb;
if (lread(fsfd, 1 * BSIZE, &sb, sizeof(sb)) != sizeof(sb)) return 1;
printf("size = %d\n", sb.size);
printf("nblocks = %d\n", sb.nblocks);
printf("ninodes = %d\n", sb.ninodes);
printf("nlog = %d\n", sb.nlog);
printf("logstart = %d\n", sb.logstart);
printf("inodestart = %d\n", sb.inodestart);
printf("bmapstart = %d\n", sb.bmapstart);
printf("dinode sz = %d\n", sizeof(struct dinode));
int dpos = sb.inodestart * BSIZE;
struct dinode di;
char *type[] = {"?", "DIR ", "FILE", "DEV "};
for(int ino = 0; ino < sb.ninodes; ino++) {
if (lread(fsfd, dpos, &di, sizeof(di)) != sizeof(di)) return 1;
dpos += sizeof(di);
if (di.nlink == 0) continue;
printf("%d: %s links: %d size: %d\n", ino, type[di.type], di.nlink, di.size);
}
// Fetch inode #3 into di:
if (lread(fsfd, (sb.inodestart * BSIZE) + (3*sizeof(di)), &di, sizeof(di)) != sizeof(di)) return 1;
int size;
char *data = readfile(fsfd, di, &size);
for(int i=0; i < size; i++) putchar(data[i]);
return 0;
}
char *readfile(int fsfd, struct dinode di, int *size)
{
char buf[BSIZE];
uint indirect[NINDIRECT];
int sz = di.size, rd = 0;
int blks = sz/BSIZE, blk = 0, db;
char *data = NULL;
if (blks >= NDIRECT) lread(fsfd, di.addrs[NDIRECT], indirect, BSIZE);
for(blk = 0; sz > 0; blk++) {
if (blk < NDIRECT) db = di.addrs[blk];
else db = indirect[blk-NDIRECT];
lread(fsfd, db * BSIZE, buf, BSIZE);
int mx = sz < BSIZE? sz: BSIZE;
data = realloc(data, rd+mx);
memcpy(data+rd, buf, mx);
rd += mx;
sz -= mx;
}
printf("Read %d bytes\n", rd);
*size = rd;
return data;
}
int lread(int fd, int bpos, void *buf, int size)
{
int n;
if (lseek(fd, bpos, SEEK_SET) != bpos) {
perror("lseek");
return -1;
}
if ( (n = read(fd, buf, size)) < 0) {
perror("read");
return -1;
}
return n;
}
|