tolerate running out of inodes

This commit is contained in:
Robert Morris 2022-08-23 12:26:26 -04:00
parent 948cfbdb1f
commit 7c1810e1ae
3 changed files with 48 additions and 9 deletions

View file

@ -193,7 +193,8 @@ static struct inode* iget(uint dev, uint inum);
// Allocate an inode on device dev. // Allocate an inode on device dev.
// Mark it as allocated by giving it type type. // Mark it as allocated by giving it type type.
// Returns an unlocked but allocated and referenced inode. // Returns an unlocked but allocated and referenced inode,
// or NULL if there is no free inode..
struct inode* struct inode*
ialloc(uint dev, short type) ialloc(uint dev, short type)
{ {
@ -213,7 +214,8 @@ ialloc(uint dev, short type)
} }
brelse(bp); brelse(bp);
} }
panic("ialloc: no inodes"); printf("ialloc: no inodes\n");
return 0;
} }
// Copy a modified in-memory inode to disk. // Copy a modified in-memory inode to disk.

View file

@ -262,8 +262,10 @@ create(char *path, short type, short major, short minor)
return 0; return 0;
} }
if((ip = ialloc(dp->dev, type)) == 0) if((ip = ialloc(dp->dev, type)) == 0){
panic("create: ialloc"); iunlockput(dp);
return 0;
}
ilock(ip); ilock(ip);
ip->major = major; ip->major = major;

View file

@ -2750,6 +2750,7 @@ diskfull(char *s)
unlink(name); unlink(name);
int fd = open(name, O_CREATE|O_RDWR|O_TRUNC); int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
if(fd < 0){ if(fd < 0){
// oops, ran out of inodes before running out of blocks.
printf("%s: could not create file %s\n", s, name); printf("%s: could not create file %s\n", s, name);
done = 1; done = 1;
break; break;
@ -2767,7 +2768,8 @@ diskfull(char *s)
// now that there are no free blocks, test that dirlink() // now that there are no free blocks, test that dirlink()
// merely fails (doesn't panic) if it can't extend // merely fails (doesn't panic) if it can't extend
// directory content. // directory content. one of these file creations
// is expected to fail.
int nzz = 128; int nzz = 128;
for(int i = 0; i < nzz; i++){ for(int i = 0; i < nzz; i++){
char name[32]; char name[32];
@ -2778,14 +2780,15 @@ diskfull(char *s)
name[4] = '\0'; name[4] = '\0';
unlink(name); unlink(name);
int fd = open(name, O_CREATE|O_RDWR|O_TRUNC); int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
if(fd < 0){ if(fd < 0)
printf("%s: could not create file %s\n", s, name);
break; break;
}
close(fd); close(fd);
} }
mkdir("diskfulldir"); // this mkdir() is expected to fail.
if(mkdir("diskfulldir") == 0)
printf("%s: mkdir(diskfulldir) unexpectedly succeeded!\n");
unlink("diskfulldir"); unlink("diskfulldir");
for(int i = 0; i < nzz; i++){ for(int i = 0; i < nzz; i++){
@ -2809,6 +2812,37 @@ diskfull(char *s)
} }
} }
void
outofinodes(char *s)
{
int nzz = 32*32;
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){
// failure is eventually expected.
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);
}
}
// //
// use sbrk() to count how many free physical memory pages there are. // use sbrk() to count how many free physical memory pages there are.
// touches the pages to force allocation. // touches the pages to force allocation.
@ -2986,6 +3020,7 @@ main(int argc, char *argv[])
{badarg, "badarg" }, {badarg, "badarg" },
{execout, "execout"}, {execout, "execout"},
{diskfull, "diskfull"}, {diskfull, "diskfull"},
{outofinodes, "outofinodes"},
{ 0, 0}, { 0, 0},
}; };