diff options
author | Robert Morris <[email protected]> | 2022-08-23 08:52:15 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2022-08-23 08:52:15 -0400 |
commit | 8621be8f3d105cd73ffbc681f9810d04b083b0ae (patch) | |
tree | 29f4d3527c6a2433dc185cee95bb258107261629 /kernel | |
parent | dc405cdb7b4e4d4bb3fc50b3e7f44e8795c0218e (diff) | |
download | xv6-labs-8621be8f3d105cd73ffbc681f9810d04b083b0ae.tar.gz xv6-labs-8621be8f3d105cd73ffbc681f9810d04b083b0ae.tar.bz2 xv6-labs-8621be8f3d105cd73ffbc681f9810d04b083b0ae.zip |
tolerate out of disk when creating . and .. in mkdir()
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sysfile.c | 25 |
1 files changed, 16 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 |