diff --git a/fs.c b/fs.c index fa71c6e..d5cc899 100644 --- a/fs.c +++ b/fs.c @@ -412,6 +412,8 @@ namei(char *path, uint *ret_pinum) pinum = dp->inum; iput(dp); dp = iget(dev, ninum); + if(dp->type == 0 || dp->nlink < 1) + panic("namei"); while(*cp == '/') cp++; } @@ -443,7 +445,7 @@ mknod(char *cp, short type, short major, short minor) ip->major = major; ip->minor = minor; ip->size = 0; - ip->nlink = 0; + ip->nlink = 1; iupdate (ip); // write new inode to disk @@ -467,8 +469,8 @@ mknod(char *cp, short type, short major, short minor) brelse(bp); dp->size += sizeof(struct dirent); // update directory inode iupdate (dp); - iput(dp); - return ip; + iput(dp); + return ip; } int diff --git a/usertests.c b/usertests.c index 12fa6f8..a3bb284 100644 --- a/usertests.c +++ b/usertests.c @@ -157,6 +157,7 @@ sharedfd() } } close(fd); + unlink("sharedfd"); if(nc == 1000 && np == 1000) printf(1, "sharedfd ok\n"); else @@ -219,14 +220,127 @@ twofiles() } } + unlink("f1"); + unlink("f2"); + puts("twofiles ok\n"); } +// two processes create and delete files in same directory +void +createdelete() +{ + int pid, i, fd; + int n = 10; // for now, fit in one directory block + char name[32]; + + pid = fork(); + if(pid < 0){ + puts("fork failed\n"); + exit(); + } + + name[0] = pid ? 'p' : 'c'; + name[2] = '\0'; + for(i = 0; i < n; i++){ + name[1] = '0' + i; + fd = open(name, O_CREATE | O_RDWR); + if(fd < 0){ + puts("create failed\n"); + exit(); + } + close(fd); + if(i > 0 && (i % 2 ) == 0){ + name[1] = '0' + (i / 2); + if(unlink(name) < 0){ + puts("unlink failed\n"); + exit(); + } + } + } + + if(pid) + wait(); + else + exit(); + + for(i = 0; i < n; i++){ + name[0] = 'p'; + name[1] = '0' + i; + fd = open(name, 0); + if((i == 0 || i >= n/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + } else if((i >= 1 && i < n/2) && fd >= 0){ + printf(1, "oops createdelete %s did exist\n", name); + } + if(fd >= 0) + close(fd); + + name[0] = 'c'; + name[1] = '0' + i; + fd = open(name, 0); + if((i == 0 || i >= n/2) && fd < 0){ + printf(1, "oops createdelete %s didn't exist\n", name); + } else if((i >= 1 && i < n/2) && fd >= 0){ + printf(1, "oops createdelete %s did exist\n", name); + } + if(fd >= 0) + close(fd); + } + + for(i = 0; i < n; i++){ + name[0] = 'p'; + name[1] = '0' + i; + unlink(name); + name[0] = 'c'; + unlink(name); + } + + printf(1, "createdelete ok\n"); +} + +// can I unlink a file and still read it? +void +unlinkread() +{ + int fd; + + fd = open("unlinkread", O_CREATE | O_RDWR); + if(fd < 0){ + puts("create unlinkread failed\n"); + exit(); + } + write(fd, "hello", 5); + close(fd); + + fd = open("unlinkread", O_RDWR); + if(fd < 0){ + puts("open unlinkread failed\n"); + exit(); + } + if(unlink("unlinkread") != 0){ + puts("unlink unlinkread failed\n"); + exit(); + } + if(read(fd, buf, sizeof(buf)) != 5){ + puts("unlinkread read failed"); + exit(); + } + if(write(fd, buf, 10) != 10){ + puts("unlinkread write failed\n"); + exit(); + } + close(fd); + puts("unlinkread ok\n"); +} + int main(int argc, char *argv[]) { puts("usertests starting\n"); + unlinkread(); + createdelete(); twofiles(); sharedfd(); pipe1();