diff --git a/kernel/sysfile.c b/kernel/sysfile.c index 4c0470e..d8a6fca 100644 --- a/kernel/sysfile.c +++ b/kernel/sysfile.c @@ -272,24 +272,31 @@ create(char *path, short type, short major, short minor) iupdate(ip); if(type == T_DIR){ // Create . and .. entries. - dp->nlink++; // for ".." - iupdate(dp); // No ip->nlink++ for ".": avoid cyclic ref count. if(dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0) - panic("create dots"); + goto fail; } - if(dirlink(dp, name, ip->inum) < 0){ - // oops. we don't need ip after all. - ip->nlink = 0; - iupdate(ip); - iunlockput(ip); - ip = 0; + if(dirlink(dp, name, ip->inum) < 0) + goto fail; + + if(type == T_DIR){ + // now that success is guaranteed: + dp->nlink++; // for ".." + iupdate(dp); } iunlockput(dp); return ip; + + fail: + // something went wrong. de-allocate ip. + ip->nlink = 0; + iupdate(ip); + iunlockput(ip); + iunlockput(dp); + return 0; } uint64 diff --git a/user/usertests.c b/user/usertests.c index 968034a..60d1762 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -2712,6 +2712,8 @@ diskfull(char *s) { int fi; int done = 0; + + unlink("diskfulldir"); for(fi = 0; done == 0; fi++){ char name[32]; @@ -2758,6 +2760,9 @@ diskfull(char *s) close(fd); } + mkdir("diskfulldir"); + unlink("diskfulldir"); + for(int i = 0; i < nzz; i++){ char name[32]; name[0] = 'z';