diff options
| -rw-r--r-- | kernel/sysfile.c | 25 | ||||
| -rw-r--r-- | user/usertests.c | 5 | 
2 files changed, 21 insertions, 9 deletions
| 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'; | 
