summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2022-08-23 08:23:12 -0400
committerRobert Morris <[email protected]>2022-08-23 08:23:12 -0400
commitdc405cdb7b4e4d4bb3fc50b3e7f44e8795c0218e (patch)
treeeaedc212d1383b65009dd6f6ea8a63fcf82daedc
parentcd6207a972cf7692dceb837f460234eae9df5052 (diff)
downloadxv6-labs-dc405cdb7b4e4d4bb3fc50b3e7f44e8795c0218e.tar.gz
xv6-labs-dc405cdb7b4e4d4bb3fc50b3e7f44e8795c0218e.tar.bz2
xv6-labs-dc405cdb7b4e4d4bb3fc50b3e7f44e8795c0218e.zip
don't panic if out of disk space when extending a directory.
-rw-r--r--kernel/fs.c3
-rw-r--r--kernel/sysfile.c9
-rw-r--r--user/usertests.c30
3 files changed, 39 insertions, 3 deletions
diff --git a/kernel/fs.c b/kernel/fs.c
index 247a86f..b220491 100644
--- a/kernel/fs.c
+++ b/kernel/fs.c
@@ -573,6 +573,7 @@ dirlookup(struct inode *dp, char *name, uint *poff)
}
// Write a new directory entry (name, inum) into the directory dp.
+// Returns 0 on success, -1 on failure (e.g. out of disk blocks).
int
dirlink(struct inode *dp, char *name, uint inum)
{
@@ -597,7 +598,7 @@ dirlink(struct inode *dp, char *name, uint inum)
strncpy(de.name, name, DIRSIZ);
de.inum = inum;
if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
- panic("dirlink");
+ return -1;
return 0;
}
diff --git a/kernel/sysfile.c b/kernel/sysfile.c
index 970a72a..4c0470e 100644
--- a/kernel/sysfile.c
+++ b/kernel/sysfile.c
@@ -279,8 +279,13 @@ create(char *path, short type, short major, short minor)
panic("create dots");
}
- if(dirlink(dp, name, ip->inum) < 0)
- panic("create: dirlink");
+ if(dirlink(dp, name, ip->inum) < 0){
+ // oops. we don't need ip after all.
+ ip->nlink = 0;
+ iupdate(ip);
+ iunlockput(ip);
+ ip = 0;
+ }
iunlockput(dp);
diff --git a/user/usertests.c b/user/usertests.c
index 4ab34da..968034a 100644
--- a/user/usertests.c
+++ b/user/usertests.c
@@ -2738,6 +2738,36 @@ diskfull(char *s)
close(fd);
}
+ // now that there are no free blocks, test that dirlink()
+ // merely fails (doesn't panic) if it can't extend
+ // directory content.
+ int nzz = 128;
+ for(int i = 0; i < nzz; i++){
+ char name[32];
+ name[0] = 'z';
+ name[1] = 'z';
+ name[2] = '0' + (i / 32);
+ name[3] = '0' + (i % 32);
+ name[4] = '\0';
+ unlink(name);
+ int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
+ if(fd < 0){
+ printf("%s: could not create file %s\n", s, name);
+ break;
+ }
+ close(fd);
+ }
+
+ for(int i = 0; i < nzz; i++){
+ char name[32];
+ name[0] = 'z';
+ name[1] = 'z';
+ name[2] = '0' + (i / 32);
+ name[3] = '0' + (i % 32);
+ name[4] = '\0';
+ unlink(name);
+ }
+
for(int i = 0; i < fi; i++){
char name[32];
name[0] = 'b';