diff options
author | kaashoek <kaashoek> | 2006-08-08 18:07:37 +0000 |
---|---|---|
committer | kaashoek <kaashoek> | 2006-08-08 18:07:37 +0000 |
commit | e8d11c2e846ad15b32caacc8a919722b76d00f79 (patch) | |
tree | 057169eaa21dc0151931d8e30072ce0d26d89bcf /fs.c | |
parent | 104207726be721843e44b8616faa87222aa5f0c2 (diff) | |
download | xv6-labs-e8d11c2e846ad15b32caacc8a919722b76d00f79.tar.gz xv6-labs-e8d11c2e846ad15b32caacc8a919722b76d00f79.tar.bz2 xv6-labs-e8d11c2e846ad15b32caacc8a919722b76d00f79.zip |
mknod,ialloc,iupdate
Diffstat (limited to 'fs.c')
-rw-r--r-- | fs.c | 95 |
1 files changed, 95 insertions, 0 deletions
@@ -54,6 +54,8 @@ iget(uint dev, uint inum) bp = bread(dev, inum / IPB + 2); dip = &((struct dinode *)(bp->data))[inum % IPB]; nip->type = dip->type; + nip->major = dip->major; + nip->minor = dip->minor; nip->nlink = dip->nlink; nip->size = dip->size; memmove(nip->addrs, dip->addrs, sizeof(nip->addrs)); @@ -62,6 +64,61 @@ iget(uint dev, uint inum) return nip; } +// allocate an inode on disk +struct inode * +ialloc(uint dev, short type) +{ + struct inode *ip; + struct dinode *dip = 0; + struct superblock *sb; + int ninodes; + int inum; + struct buf *bp; + + bp = bread(dev, 1); + sb = (struct superblock *) bp; + ninodes = sb->ninodes; + brelse(bp); + + for (inum = 1; inum < ninodes; inum++) { // loop over inode blocks + bp = bread(dev, inum / IPB + 2); + dip = &((struct dinode *)(bp->data))[inum % IPB]; + if (dip->type == 0) { // a free inode + break; + } + brelse(bp); + } + + if (inum >= ninodes) { + cprintf ("ialloc: no inodes left\n"); + return 0; + } + + cprintf ("ialloc: %d\n", inum); + dip->type = type; + bwrite (dev, bp, inum / IPB + 2); // mark it allocated on the disk + brelse(bp); + ip = iget (dev, inum); + return ip; +} + +void +iupdate (struct inode *ip) +{ + struct buf *bp; + struct dinode *dip; + + bp = bread(ip->dev, ip->inum / IPB + 2); + dip = &((struct dinode *)(bp->data))[ip->inum % IPB]; + dip->type = ip->type; + dip->major = ip->major; + dip->minor = ip->minor; + dip->nlink = ip->nlink; + dip->size = ip->size; + bwrite (ip->dev, bp, ip->inum / IPB + 2); // mark it allocated on the disk + brelse(bp); +} + void ilock(struct inode *ip) { @@ -214,3 +271,41 @@ namei(char *path) cp++; } } + +struct inode * +mknod(struct inode *dp, char *cp, short type, short major, short minor) +{ + struct inode *ip; + struct dirent *ep = 0; + int off; + int i; + struct buf *bp = 0; + + cprintf("mknod: %s %d %d %d\n", cp, type, major, minor); + + ip = ialloc(dp->dev, type); + if (ip == 0) return 0; + ip->major = major; + ip->minor = minor; + + 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) { + goto found; + } + } + brelse(bp); + } + panic("mknod: no dir entry free\n"); + + found: + ep->inum = ip->inum; + for(i = 0; i < DIRSIZ && cp[i]; i++) ep->name[i] = cp[i]; + bwrite (dp->dev, bp, bmap(dp, off/512)); // write directory + brelse(bp); + iupdate (ip); + return ip; +} |