diff --git a/fs.c b/fs.c index a6c4732..fb82f91 100644 --- a/fs.c +++ b/fs.c @@ -143,7 +143,7 @@ iinit(void) } // 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* iget(uint dev, uint inum) { @@ -255,6 +255,7 @@ iput(struct inode *ip) release(&icache.lock); } +// Common idiom: unlock, then put. void iunlockput(struct inode *ip) { @@ -275,7 +276,7 @@ ialloc(uint dev, short type) readsb(dev, &sb); for(inum = 1; inum < sb.ninodes; inum++) { // loop over inode blocks 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 memset(dip, 0, sizeof(*dip)); dip->type = type; @@ -296,7 +297,7 @@ iupdate(struct inode *ip) struct dinode *dip; 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->major = ip->major; dip->minor = ip->minor; @@ -312,7 +313,7 @@ iupdate(struct inode *ip) // // The contents (data) associated with each inode is stored // 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]. // 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); } - if(off + n < off) + if(off > ip->size || off + n < off) return -1; if(off + n > ip->size) n = ip->size - off; @@ -486,8 +487,8 @@ dirlookup(struct inode *dp, char *name, uint *poff) for(off = 0; off < dp->size; off += BSIZE){ bp = bread(dp->dev, bmap(dp, off / BSIZE, 0)); - for(de = (struct dirent*) bp->data; - de < (struct dirent*) (bp->data + BSIZE); + for(de = (struct dirent*)bp->data; + de < (struct dirent*)(bp->data + BSIZE); de++){ if(de->inum == 0) continue; @@ -522,7 +523,7 @@ dirlink(struct inode *dp, char *name, uint ino) // Look for an empty dirent. for(off = 0; off < dp->size; off += sizeof(de)){ if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) - panic("dirwrite read"); + panic("dirlink read"); if(de.inum == 0) break; } @@ -530,7 +531,7 @@ dirlink(struct inode *dp, char *name, uint ino) strncpy(de.name, name, DIRSIZ); de.inum = ino; if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de)) - panic("dirwrite"); + panic("dirlink"); return 0; } @@ -546,7 +547,7 @@ dirlink(struct inode *dp, char *name, uint ino) // // Examples: // 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 // static char* @@ -574,21 +575,6 @@ skipelem(char *path, char *name) 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. // If parent is set, return the inode for the parent // and write the final path element to name, which @@ -597,7 +583,6 @@ static struct inode* _namei(char *path, int parent, char *name) { struct inode *ip, *next; - uint off; if(*path == '/') ip = iget(ROOTDEV, 1); @@ -610,14 +595,12 @@ _namei(char *path, int parent, char *name) iunlockput(ip); return 0; } - if(parent && *path == '\0'){ // Stop one level early. iunlock(ip); return ip; } - - if((next = dirlookup(ip, name, &off)) == 0){ + if((next = dirlookup(ip, name, 0)) == 0){ iunlockput(ip); return 0; } @@ -631,3 +614,14 @@ _namei(char *path, int parent, char *name) 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); +}