From 1be766853771bda6023b8024041453413fb777bb Mon Sep 17 00:00:00 2001 From: kaashoek Date: Thu, 24 Aug 2006 17:28:01 +0000 Subject: [PATCH] fix bugs in indirect-file code clean up test program --- fs.c | 21 ++++---- userfs.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 143 insertions(+), 36 deletions(-) diff --git a/fs.c b/fs.c index 6a1c1d0..cd60da9 100644 --- a/fs.c +++ b/fs.c @@ -241,8 +241,7 @@ bmap(struct inode *ip, uint bn) if (x == 0) panic("bmap 2"); } else { - cprintf("indirect block read\n"); - inbp = bread(ip->dev, INDIRECT); + inbp = bread(ip->dev, ip->addrs[INDIRECT]); a = (uint *) inbp->data; x = a[bn - NDIRECT]; brelse(inbp); @@ -256,21 +255,23 @@ void iunlink(struct inode *ip) { int i, j; + struct buf *inbp; // free inode, its blocks, and remove dir entry for (i = 0; i < NADDRS; i++) { if (ip->addrs[i] != 0) { if (i == INDIRECT) { + inbp = bread(ip->dev, ip->addrs[INDIRECT]); for (j = 0; j < NINDIRECT; j++) { - uint *a = (uint *) (ip->addrs[i]); + uint *a = (uint *) inbp->data; if (a[j] != 0) { bfree(ip->dev, a[j]); a[j] = 0; } } - } - else - bfree(ip->dev, ip->addrs[i]); + brelse(inbp); + } + bfree(ip->dev, ip->addrs[i]); ip->addrs[i] = 0; } } @@ -354,7 +355,7 @@ readi(struct inode *ip, char *dst, uint off, uint n) return target - n; } -int +static int newblock(struct inode *ip, uint lbn) { struct buf *inbp; @@ -368,20 +369,18 @@ newblock(struct inode *ip, uint lbn) ip->addrs[lbn] = b; } } else { - cprintf("newblock: use indirect block\n"); if (ip->addrs[INDIRECT] == 0) { - cprintf("newblock: allocate indirect block\n"); b = balloc(ip->dev); if (b <= 0) return -1; ip->addrs[INDIRECT] = b; } - inbp = bread(ip->dev, bmap(ip, INDIRECT)); + inbp = bread(ip->dev, ip->addrs[INDIRECT]); inaddrs = (uint *) inbp->data; if (inaddrs[lbn - NDIRECT] == 0) { b = balloc(ip->dev); if (b <= 0) return -1; inaddrs[lbn - NDIRECT] = b; - bwrite(inbp, INDIRECT); + bwrite(inbp, ip->addrs[INDIRECT]); } brelse(inbp); } diff --git a/userfs.c b/userfs.c index 54bc334..47add52 100644 --- a/userfs.c +++ b/userfs.c @@ -4,25 +4,18 @@ #include "fs.h" #include "fcntl.h" -// file system tests +// simple file system tests char buf[2000]; char name[3]; char *echo_args[] = { "echo", "hello", "goodbye", 0 }; char *cat_args[] = { "cat", "readme", 0 }; +int stdout = 1; -int -main(void) +void +opentest(void) { int fd; - int i; - int stdout = 1; - - printf(stdout, "userfs is running\n"); - - if (sbrk(4096) < 0) { - printf(stdout, "sbrk failed\n"); - } fd = open("echo", 0); if(fd >= 0){ @@ -30,47 +23,123 @@ main(void) close(fd); } else { printf(stdout, "open echo failed!\n"); + exit(); } fd = open("doesnotexist", 0); if(fd >= 0){ printf(stdout, "open doesnotexist succeeded!\n"); - close(fd); + exit(); } else { printf(stdout, "open doesnotexist failed\n"); } - fd = open("doesnotexist", O_CREATE|O_RDWR); +} + +void +writetest(void) +{ + int fd; + int i; + + fd = open("small", O_CREATE|O_RDWR); if(fd >= 0){ - printf(stdout, "creat doesnotexist succeeded\n"); + printf(stdout, "creat small succeeded\n"); } else { - printf(stdout, "error: creat doesnotexist failed!\n"); + printf(stdout, "error: creat small failed!\n"); + exit(); } for (i = 0; i < 100; i++) { if (write (fd, "aaaaaaaaaa", 10) != 10) { printf(stdout, "error: write aa %d new file failed\n", i); + exit(); } if (write (fd, "bbbbbbbbbb", 10) != 10) { printf(stdout, "error: write bb %d new file failed\n", i); + exit(); } } printf(stdout, "writes done\n"); close(fd); - fd = open("doesnotexist", O_RDONLY); + fd = open("small", O_RDONLY); if(fd >= 0){ - printf(stdout, "open doesnotexist succeeded\n"); + printf(stdout, "open small succeeded\n"); } else { - printf(stdout, "error: open doesnotexist failed!\n"); + printf(stdout, "error: open small failed!\n"); + exit(); } i = read(fd, buf, 2000); if (i == 2000) { printf(stdout, "read succeeded\n"); } else { printf(stdout, "read failed\n"); + exit(); } close(fd); - printf(stdout, "unlink doesnotexist\n"); + if (unlink("small") < 0) { + printf(stdout, "unlink small failed\n"); + exit(); + } +} - unlink("doesnotexist"); +void +writetest1(void) +{ + int i, fd, n; + + printf(stdout, "big files\n"); + + fd = open("big", O_CREATE|O_RDWR); + if(fd < 0){ + printf(stdout, "error: creat big failed!\n"); + exit(); + } + + for (i = 0; i < MAXFILE; i++) { + ((int *) buf)[0] = i; + if (write (fd, buf, 512) != 512) { + printf(stdout, "error: write big file failed\n", i); + exit(); + } + } + + close(fd); + + fd = open("big", O_RDONLY); + if(fd < 0){ + printf(stdout, "error: open big failed!\n"); + exit(); + } + + n = 0; + while (1) { + i = read(fd, buf, 512); + if (i == 0) { + if (n == MAXFILE - 1) { + printf(stdout, "read only %d blocks from big", n); + exit(); + } + break; + } else if (i != 512) { + printf(stdout, "read failed %d\n", i); + exit(); + } + if (((int *)buf)[0] != n) { + printf(stdout, "read content of block %d is %d\n", n, ((int *)buf)[0]); + exit(); + } + n++; + } + close(fd); + if (unlink("big") < 0) { + printf(stdout, "unlink big failed\n"); + exit(); + } +} + +void +createtest(void) +{ + int i, fd; printf(stdout, "many creates, followed by unlink\n"); @@ -87,16 +156,55 @@ main(void) name[1] = '0' + i; unlink(name); } +} +void dirtest(void) +{ printf(stdout, "mkdir\n"); - if (mkdir("dir0") < 0) + if (mkdir("dir0") < 0) { printf(stdout, "mkdir failed\n"); + exit(); + } - // unlink("dir0"); + if (chdir("dir0") < 0) { + printf(stdout, "chdir dir0 failed\n"); + exit(); + } - //exec("echo", echo_args); - printf(stdout, "about to do exec\n"); - exec("cat", cat_args); + if (chdir("..") < 0) { + printf(stdout, "chdir .. failed\n"); + exit (); + } + + if (unlink("dir0") < 0) { + printf(stdout, "unlink dir0 failed\n"); + exit(); + } +} + +void +exectest(void) +{ + if (exec("echo", echo_args) < 0) { + printf(stdout, "exec echo failed\n"); + exit(); + } + if (exec("cat", cat_args) < 0) { + printf(stdout, "exec cat failed\n"); + exit(); + } +} + +int +main(void) +{ + printf(stdout, "userfs is running\n"); + + opentest(); + writetest(); + writetest1(); + createtest(); + exectest(); return 0; }