diff --git a/Notes b/Notes index 4c9855dd67904435d4dc731dd02b2ac6c9b1c88b..6273db5a02e501ba0ed0cfe9509df2027d0733c1 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 cd60da9eb0d08c89aeba2454a967e5a65cbeafc5..5280a4d18f5991ef580a742168b58217799b32d9 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 e42851964de31441bc10c3759b1891ed192908b7..d177ce90773b240fcb0db47772c1325448bd8e34 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();