diff options
author | rtm <rtm> | 2006-07-21 22:10:40 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-07-21 22:10:40 +0000 |
commit | 9d3fb6714181f44300a0a5431279841427e4ef06 (patch) | |
tree | b201602d7ff5e1a9ce51554bdf8c417f7caaa192 /fs.c | |
parent | 11a9947f1a68e23001690955d8d0975ad4d6cf0c (diff) | |
download | xv6-labs-9d3fb6714181f44300a0a5431279841427e4ef06.tar.gz xv6-labs-9d3fb6714181f44300a0a5431279841427e4ef06.tar.bz2 xv6-labs-9d3fb6714181f44300a0a5431279841427e4ef06.zip |
namei
Diffstat (limited to 'fs.c')
-rw-r--r-- | fs.c | 119 |
1 files changed, 118 insertions, 1 deletions
@@ -14,6 +14,9 @@ struct inode inode[NINODE]; struct spinlock inode_table_lock; +uint rootdev = 1; + +// returns an inode with busy set and incremented reference count. struct inode * iget(uint dev, uint inum) { @@ -54,15 +57,50 @@ iget(uint dev, uint inum) nip->nlink = dip->nlink; nip->size = dip->size; memmove(nip->addrs, dip->addrs, sizeof(nip->addrs)); - cprintf("bn %d off %d\n", inum / IPB + 2, (unsigned)dip - (unsigned)bp->data); brelse(bp); return nip; } void +ilock(struct inode *ip) +{ + if(ip->count < 1) + panic("ilock"); + + acquire(&inode_table_lock); + + while(ip->busy) + sleep(ip, &inode_table_lock); + ip->busy = 1; + + release(&inode_table_lock); +} + +// caller is holding onto a reference to this inode, but no +// longer needs to examine or change it, so clear ip->busy. +void +iunlock(struct inode *ip) +{ + if(ip->busy != 1) + panic("iunlock"); + + acquire(&inode_table_lock); + + ip->busy = 0; + wakeup(ip); + + release(&inode_table_lock); +} + +// caller is releasing a reference to this inode. +// you must have the inode lock. +void iput(struct inode *ip) { + if(ip->count < 1 || ip->busy != 1) + panic("iput"); + acquire(&inode_table_lock); ip->count -= 1; @@ -71,3 +109,82 @@ iput(struct inode *ip) release(&inode_table_lock); } + +void +iincref(struct inode *ip) +{ + acquire(&inode_table_lock); + + ip->count += 1; + + release(&inode_table_lock); +} + +uint +bmap(struct inode *ip, uint bn) +{ + unsigned x; + + if(bn >= NDIRECT) + panic("bmap 1"); + x = ip->addrs[bn]; + if(x == 0) + panic("bmap 2"); + return x; +} + +struct inode * +namei(char *path) +{ + struct inode *dp; + char *cp = path; + uint off, dev; + struct buf *bp; + struct dirent *ep; + int i; + unsigned ninum; + + dp = iget(rootdev, 1); + + while(*cp == '/') + cp++; + + while(1){ + if(*cp == '\0') + return dp; + + if(dp->type != T_DIR){ + iput(dp); + return 0; + } + + for(off = 0; off < dp->size; off += 512){ + bp = bread(dp->dev, bmap(dp, off / 512)); + for(ep = (struct dirent *) bp->data; + ep < (struct dirent *) (bp->data + 512); + ep++){ + if(ep->inum == 0) + continue; + for(i = 0; i < DIRSIZ && cp[i] != '/' && cp[i]; i++) + if(cp[i] != ep->name[i]) + break; + if((cp[i] == '\0' || cp[i] == '/') && (i >= DIRSIZ || ep->name[i] == '\0')){ + ninum = ep->inum; + brelse(bp); + cp += i; + goto found; + } + } + brelse(bp); + } + iput(dp); + return 0; + + found: + dev = dp->dev; + iput(dp); + dp = iget(dev, ninum); + while(*cp == '/') + cp++; + } +} |