This commit is contained in:
rsc 2007-08-27 14:31:50 +00:00
parent 6c34f97cb8
commit 7895178df3

52
fs.c
View file

@ -143,7 +143,7 @@ iinit(void)
} }
// Find the inode with number inum on device dev // Find the inode with number inum on device dev
// and return the in-memory copy. h // and return the in-memory copy.
static struct inode* static struct inode*
iget(uint dev, uint inum) iget(uint dev, uint inum)
{ {
@ -255,6 +255,7 @@ iput(struct inode *ip)
release(&icache.lock); release(&icache.lock);
} }
// Common idiom: unlock, then put.
void void
iunlockput(struct inode *ip) iunlockput(struct inode *ip)
{ {
@ -275,7 +276,7 @@ ialloc(uint dev, short type)
readsb(dev, &sb); readsb(dev, &sb);
for(inum = 1; inum < sb.ninodes; inum++) { // loop over inode blocks for(inum = 1; inum < sb.ninodes; inum++) { // loop over inode blocks
bp = bread(dev, IBLOCK(inum)); bp = bread(dev, IBLOCK(inum));
dip = &((struct dinode*)(bp->data))[inum % IPB]; dip = (struct dinode*)(bp->data) + inum%IPB;
if(dip->type == 0) { // a free inode if(dip->type == 0) { // a free inode
memset(dip, 0, sizeof(*dip)); memset(dip, 0, sizeof(*dip));
dip->type = type; dip->type = type;
@ -296,7 +297,7 @@ iupdate(struct inode *ip)
struct dinode *dip; struct dinode *dip;
bp = bread(ip->dev, IBLOCK(ip->inum)); bp = bread(ip->dev, IBLOCK(ip->inum));
dip = &((struct dinode*)(bp->data))[ip->inum % IPB]; dip = (struct dinode*)(bp->data) + ip->inum%IPB;
dip->type = ip->type; dip->type = ip->type;
dip->major = ip->major; dip->major = ip->major;
dip->minor = ip->minor; dip->minor = ip->minor;
@ -312,7 +313,7 @@ iupdate(struct inode *ip)
// //
// The contents (data) associated with each inode is stored // The contents (data) associated with each inode is stored
// in a sequence of blocks on the disk. The first NDIRECT blocks // in a sequence of blocks on the disk. The first NDIRECT blocks
// are stored in ip->addrs[]. The next NINDIRECT blocks are // are listed in ip->addrs[]. The next NINDIRECT blocks are
// listed in the block ip->addrs[INDIRECT]. // listed in the block ip->addrs[INDIRECT].
// Return the disk block address of the nth block in inode ip. // Return the disk block address of the nth block in inode ip.
@ -414,7 +415,7 @@ readi(struct inode *ip, char *dst, uint off, uint n)
return devsw[ip->major].read(ip->minor, dst, n); return devsw[ip->major].read(ip->minor, dst, n);
} }
if(off + n < off) if(off > ip->size || off + n < off)
return -1; return -1;
if(off + n > ip->size) if(off + n > ip->size)
n = ip->size - off; n = ip->size - off;
@ -486,8 +487,8 @@ dirlookup(struct inode *dp, char *name, uint *poff)
for(off = 0; off < dp->size; off += BSIZE){ for(off = 0; off < dp->size; off += BSIZE){
bp = bread(dp->dev, bmap(dp, off / BSIZE, 0)); bp = bread(dp->dev, bmap(dp, off / BSIZE, 0));
for(de = (struct dirent*) bp->data; for(de = (struct dirent*)bp->data;
de < (struct dirent*) (bp->data + BSIZE); de < (struct dirent*)(bp->data + BSIZE);
de++){ de++){
if(de->inum == 0) if(de->inum == 0)
continue; continue;
@ -522,7 +523,7 @@ dirlink(struct inode *dp, char *name, uint ino)
// Look for an empty dirent. // Look for an empty dirent.
for(off = 0; off < dp->size; off += sizeof(de)){ for(off = 0; off < dp->size; off += sizeof(de)){
if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
panic("dirwrite read"); panic("dirlink read");
if(de.inum == 0) if(de.inum == 0)
break; break;
} }
@ -530,7 +531,7 @@ dirlink(struct inode *dp, char *name, uint ino)
strncpy(de.name, name, DIRSIZ); strncpy(de.name, name, DIRSIZ);
de.inum = ino; de.inum = ino;
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
panic("dirwrite"); panic("dirlink");
return 0; return 0;
} }
@ -546,7 +547,7 @@ dirlink(struct inode *dp, char *name, uint ino)
// //
// Examples: // Examples:
// skipelem("a/bb/c", name) = "bb/c", setting name = "a" // skipelem("a/bb/c", name) = "bb/c", setting name = "a"
// skipelem("///a/bb", name) = "bb", setting name="a" // skipelem("///a//bb", name) = "bb", setting name = "a"
// skipelem("", name) = skipelem("////", name) = 0 // skipelem("", name) = skipelem("////", name) = 0
// //
static char* static char*
@ -574,21 +575,6 @@ skipelem(char *path, char *name)
return path; return path;
} }
static struct inode* _namei(char*, int, char*);
struct inode*
namei(char *path)
{
char name[DIRSIZ];
return _namei(path, 0, name);
}
struct inode*
nameiparent(char *path, char *name)
{
return _namei(path, 1, name);
}
// Look up and return the inode for a path name. // Look up and return the inode for a path name.
// If parent is set, return the inode for the parent // If parent is set, return the inode for the parent
// and write the final path element to name, which // and write the final path element to name, which
@ -597,7 +583,6 @@ static struct inode*
_namei(char *path, int parent, char *name) _namei(char *path, int parent, char *name)
{ {
struct inode *ip, *next; struct inode *ip, *next;
uint off;
if(*path == '/') if(*path == '/')
ip = iget(ROOTDEV, 1); ip = iget(ROOTDEV, 1);
@ -610,14 +595,12 @@ _namei(char *path, int parent, char *name)
iunlockput(ip); iunlockput(ip);
return 0; return 0;
} }
if(parent && *path == '\0'){ if(parent && *path == '\0'){
// Stop one level early. // Stop one level early.
iunlock(ip); iunlock(ip);
return ip; return ip;
} }
if((next = dirlookup(ip, name, 0)) == 0){
if((next = dirlookup(ip, name, &off)) == 0){
iunlockput(ip); iunlockput(ip);
return 0; return 0;
} }
@ -631,3 +614,14 @@ _namei(char *path, int parent, char *name)
return ip; return ip;
} }
struct inode*
namei(char *path)
{
char name[DIRSIZ];
return _namei(path, 0, name);
}
struct inode*
nameiparent(char *path, char *name)
{
return _namei(path, 1, name);
}