From bcfb84b6a9077b5e035325b3396c062d1f183ac4 Mon Sep 17 00:00:00 2001 From: rtm Date: Thu, 24 Aug 2006 19:21:19 +0000 Subject: [PATCH] big directory test --- Notes | 11 ++++++++++- fs.c | 5 ++++- fstests.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Notes b/Notes index 4c9855d..6273db5 100644 --- a/Notes +++ b/Notes @@ -115,6 +115,11 @@ why does shell often ignore first line of input? test: one process unlinks a file while another links to it test: one process opens a file while another deletes it test: mkdir. deadlock d/.. vs ../d +test: sub-sub directories. mkdir("d1/d2") +test: dup() shared fd->off +test: indirect blocks. files and directories. +test: sbrk +test: does echo foo > x truncate x? make proc[0] runnable cpu early tss and gdt @@ -138,4 +143,8 @@ are the locks in the right place in keyboardintr? sh: support pipes? leave it for the class? sh: dynamic memory allocation? sh: should sh support ; () & --- need malloc -sh: stop stdin on ctrl-d (for cat > y) \ No newline at end of file +sh: stop stdin on ctrl-d (for cat > y) + +really should have bdwrite() for file content + and make some inode updates async + so soft updates make sense diff --git a/fs.c b/fs.c index cd60da9..5280a4d 100644 --- a/fs.c +++ b/fs.c @@ -262,8 +262,8 @@ iunlink(struct inode *ip) if (ip->addrs[i] != 0) { if (i == INDIRECT) { inbp = bread(ip->dev, ip->addrs[INDIRECT]); + uint *a = (uint *) inbp->data; for (j = 0; j < NINDIRECT; j++) { - uint *a = (uint *) inbp->data; if (a[j] != 0) { bfree(ip->dev, a[j]); a[j] = 0; @@ -589,6 +589,9 @@ unlink(char *cp) ip = iget(dev, inum); + if(ip->nlink < 1) + panic("unlink nlink < 1"); + ip->nlink--; iupdate(ip); diff --git a/fstests.c b/fstests.c index e428519..d177ce9 100644 --- a/fstests.c +++ b/fstests.c @@ -365,11 +365,56 @@ concreate() puts("concreate ok\n"); } +// directory that uses indirect blocks +void +bigdir() +{ + int i, fd; + char name[10]; + + unlink("bd"); + + fd = open("bd", O_CREATE); + if(fd < 0){ + puts("bigdir create failed\n"); + exit(); + } + close(fd); + + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if(link("bd", name) != 0){ + puts("bigdir link failed\n"); + exit(); + } + puts("c"); + } + + unlink("bd"); + for(i = 0; i < 500; i++){ + name[0] = 'x'; + name[1] = '0' + (i / 64); + name[2] = '0' + (i % 64); + name[3] = '\0'; + if(unlink(name) != 0){ + puts("bigdir unlink failed"); + exit(); + } + puts("d"); + } + + puts("bigdir ok\n"); +} + int main(int argc, char *argv[]) { puts("fstests starting\n"); + bigdir(); concreate(); linktest(); unlinkread();