summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2022-08-23 08:52:15 -0400
committerRobert Morris <[email protected]>2022-08-23 08:52:15 -0400
commit8621be8f3d105cd73ffbc681f9810d04b083b0ae (patch)
tree29f4d3527c6a2433dc185cee95bb258107261629
parentdc405cdb7b4e4d4bb3fc50b3e7f44e8795c0218e (diff)
downloadxv6-labs-8621be8f3d105cd73ffbc681f9810d04b083b0ae.tar.gz
xv6-labs-8621be8f3d105cd73ffbc681f9810d04b083b0ae.tar.bz2
xv6-labs-8621be8f3d105cd73ffbc681f9810d04b083b0ae.zip
tolerate out of disk when creating . and .. in mkdir()
-rw-r--r--kernel/sysfile.c25
-rw-r--r--user/usertests.c5
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';