tolerate running out of inodes
This commit is contained in:
		
							parent
							
								
									948cfbdb1f
								
							
						
					
					
						commit
						7c1810e1ae
					
				
					 3 changed files with 48 additions and 9 deletions
				
			
		| 
						 | 
					@ -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.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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},
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue