zero freed blocks
multi-block directories track size of directory (size = number entries in use) should namei (and other code that scans through directories) scan through all blocks of a directory and not use size?
This commit is contained in:
		
							parent
							
								
									9e5970d596
								
							
						
					
					
						commit
						c372e8dc34
					
				
					 2 changed files with 34 additions and 8 deletions
				
			
		
							
								
								
									
										25
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								fs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -76,6 +76,11 @@ bfree(int dev, uint b)
 | 
			
		|||
  ninodes = sb->ninodes;
 | 
			
		||||
  brelse(bp);
 | 
			
		||||
 | 
			
		||||
  bp = bread(dev, b);
 | 
			
		||||
  memset(bp->data, 0, BSIZE);
 | 
			
		||||
  bwrite(bp, b);
 | 
			
		||||
  brelse(bp);
 | 
			
		||||
 | 
			
		||||
  bp = bread(dev, BBLOCK(b, ninodes));
 | 
			
		||||
  bi = b % BPB;
 | 
			
		||||
  m = ~(0x1 << (bi %8));
 | 
			
		||||
| 
						 | 
				
			
			@ -446,6 +451,7 @@ wdir(struct inode *dp, char *name, uint ino)
 | 
			
		|||
  struct buf *bp = 0;
 | 
			
		||||
  struct dirent *ep = 0;
 | 
			
		||||
  int i;
 | 
			
		||||
  int lb;
 | 
			
		||||
 | 
			
		||||
  for(off = 0; off < dp->size; off += BSIZE) {
 | 
			
		||||
    bp = bread(dp->dev, bmap(dp, off / BSIZE));
 | 
			
		||||
| 
						 | 
				
			
			@ -457,17 +463,23 @@ wdir(struct inode *dp, char *name, uint ino)
 | 
			
		|||
    }
 | 
			
		||||
    brelse(bp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  panic("mknod: XXXX no dir entry free\n");
 | 
			
		||||
 | 
			
		||||
  lb = dp->size / BSIZE;
 | 
			
		||||
  if (lb >= NDIRECT) {
 | 
			
		||||
    panic ("wdir: too many entries");
 | 
			
		||||
  }
 | 
			
		||||
  dp->addrs[lb] = balloc(dp->dev);
 | 
			
		||||
  bp = bread(dp->dev, dp->addrs[lb]);
 | 
			
		||||
  ep = (struct dirent *) (bp->data);
 | 
			
		||||
 found:
 | 
			
		||||
  ep->inum = ino;
 | 
			
		||||
  for(i = 0; i < DIRSIZ && name[i]; i++)
 | 
			
		||||
    ep->name[i] = name[i];
 | 
			
		||||
  for( ; i < DIRSIZ; i++)
 | 
			
		||||
    ep->name[i] = '\0';
 | 
			
		||||
  dp->size += sizeof(struct dirent);
 | 
			
		||||
  bwrite (bp, bmap(dp, off/BSIZE));   // write directory block
 | 
			
		||||
  brelse(bp);
 | 
			
		||||
  iupdate(dp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct inode *
 | 
			
		||||
| 
						 | 
				
			
			@ -482,7 +494,6 @@ mknod(char *cp, short type, short major, short minor)
 | 
			
		|||
    iput(ip);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  cprintf("mknod: pinum = %d\n", pinum);
 | 
			
		||||
  dp = iget(rootdev, pinum);
 | 
			
		||||
  ip = ialloc(dp->dev, type);
 | 
			
		||||
  if (ip == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -497,9 +508,7 @@ mknod(char *cp, short type, short major, short minor)
 | 
			
		|||
  iupdate (ip);  // write new inode to disk
 | 
			
		||||
  
 | 
			
		||||
  wdir(dp, cp, ip->inum);
 | 
			
		||||
 | 
			
		||||
  iput(dp);
 | 
			
		||||
 | 
			
		||||
  return ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -537,12 +546,14 @@ unlink(char *cp)
 | 
			
		|||
    }
 | 
			
		||||
    brelse(bp);
 | 
			
		||||
  }
 | 
			
		||||
  panic("mknod: XXXX no dir entry free\n");
 | 
			
		||||
  panic("unlink: entry doesn't exist\n");
 | 
			
		||||
 | 
			
		||||
 found:
 | 
			
		||||
  ep->inum = 0;
 | 
			
		||||
  memset(ep->name, '\0', DIRSIZ);
 | 
			
		||||
  bwrite (bp, bmap(dp, off/BSIZE));   // write directory block
 | 
			
		||||
  brelse(bp);
 | 
			
		||||
  dp->size -= sizeof(struct dirent);
 | 
			
		||||
  iupdate (dp);
 | 
			
		||||
  iput(dp);
 | 
			
		||||
  iput(ip);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								userfs.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								userfs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
// file system tests
 | 
			
		||||
 | 
			
		||||
char buf[2000];
 | 
			
		||||
char name[3];
 | 
			
		||||
char *echo_args[] = { "echo", "hello", "goodbye", 0 };
 | 
			
		||||
char *cat_args[] = { "cat", "README", 0 };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +66,20 @@ main(void)
 | 
			
		|||
  }
 | 
			
		||||
  close(fd);
 | 
			
		||||
  unlink("doesnotexist");
 | 
			
		||||
  name[0] = 'a';
 | 
			
		||||
  name[2] = '\0';
 | 
			
		||||
  for (i = 0; i < 52; i++) {
 | 
			
		||||
    name[1] = '0' + i;
 | 
			
		||||
    fd = open(name, O_CREATE|O_RDWR);
 | 
			
		||||
    close(fd);
 | 
			
		||||
  }
 | 
			
		||||
  name[0] = 'a';
 | 
			
		||||
  name[2] = '\0';
 | 
			
		||||
  for (i = 0; i < 52; i++) {
 | 
			
		||||
    name[1] = '0' + i;
 | 
			
		||||
    unlink(name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //exec("echo", echo_args);
 | 
			
		||||
  printf(stdout, "about to do exec\n");
 | 
			
		||||
  exec("cat", cat_args);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue