mknod,ialloc,iupdate

This commit is contained in:
kaashoek 2006-08-08 18:07:37 +00:00
parent 104207726b
commit e8d11c2e84
9 changed files with 152 additions and 2 deletions

1
defs.h
View file

@ -109,3 +109,4 @@ void idecref(struct inode *ip);
void iput(struct inode *ip); void iput(struct inode *ip);
struct inode * namei(char *path); struct inode * namei(char *path);
int readi(struct inode *ip, void *xdst, uint off, uint n); int readi(struct inode *ip, void *xdst, uint off, uint n);
struct inode *mknod(struct inode *, char *, short, short, short);

95
fs.c
View file

@ -54,6 +54,8 @@ iget(uint dev, uint inum)
bp = bread(dev, inum / IPB + 2); bp = bread(dev, inum / IPB + 2);
dip = &((struct dinode *)(bp->data))[inum % IPB]; dip = &((struct dinode *)(bp->data))[inum % IPB];
nip->type = dip->type; nip->type = dip->type;
nip->major = dip->major;
nip->minor = dip->minor;
nip->nlink = dip->nlink; nip->nlink = dip->nlink;
nip->size = dip->size; nip->size = dip->size;
memmove(nip->addrs, dip->addrs, sizeof(nip->addrs)); memmove(nip->addrs, dip->addrs, sizeof(nip->addrs));
@ -62,6 +64,61 @@ iget(uint dev, uint inum)
return nip; 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 void
ilock(struct inode *ip) ilock(struct inode *ip)
{ {
@ -214,3 +271,41 @@ namei(char *path)
cp++; 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;
}

6
fs.h
View file

@ -6,18 +6,22 @@ struct superblock{
int ninodes; int ninodes;
}; };
#define NDIRECT 14 #define NDIRECT 13
// inodes start at the third sector // inodes start at the third sector
// and blocks start at (ninodes * sizeof(dinode) + 511) / 512 // and blocks start at (ninodes * sizeof(dinode) + 511) / 512
struct dinode { struct dinode {
short type; short type;
short major;
short minor;
short nlink; short nlink;
uint size; uint size;
uint addrs[NDIRECT]; uint addrs[NDIRECT];
}; };
#define T_DIR 1 #define T_DIR 1
#define T_FILE 2 #define T_FILE 2
#define T_DEV 3
#define IPB (512 / sizeof(struct dinode)) #define IPB (512 / sizeof(struct dinode))

View file

@ -6,6 +6,8 @@ struct inode {
int count; int count;
int busy; int busy;
short type; short type;
short major;
short minor;
short nlink; short nlink;
uint size; uint size;
uint addrs[NDIRECT]; uint addrs[NDIRECT];

View file

@ -279,6 +279,41 @@ sys_open(void)
return ufd; return ufd;
} }
int
sys_mknod(void)
{
struct proc *cp = curproc[cpu()];
struct inode *dp, *nip;
uint arg0, arg1, arg2, arg3;
int l;
if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0 ||
fetcharg(2, &arg2) < 0 || fetcharg(3, &arg3) < 0)
return -1;
if((l = checkstring(arg0)) < 0)
return -1;
if(l >= DIRSIZ)
return -1;
dp = iget(rootdev, 1);
cprintf("root inode type: %d\n", dp->type);
if (dp->type != T_DIR)
return -1;
nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,
(short) arg3);
if (nip == 0) return -1;
iput(nip);
iput(dp);
return 0;
}
int int
sys_exec(void) sys_exec(void)
{ {
@ -515,6 +550,9 @@ syscall(void)
case SYS_open: case SYS_open:
ret = sys_open(); ret = sys_open();
break; break;
case SYS_mknod:
ret = sys_mknod();
break;
default: default:
cprintf("unknown sys call %d\n", num); cprintf("unknown sys call %d\n", num);
// XXX fault // XXX fault

View file

@ -12,3 +12,4 @@
#define SYS_cons_puts 12 #define SYS_cons_puts 12
#define SYS_exec 13 #define SYS_exec 13
#define SYS_open 14 #define SYS_open 14
#define SYS_mknod 15

2
user.h
View file

@ -10,7 +10,7 @@ int block(void);
int kill(int); int kill(int);
int panic(char*); int panic(char*);
int cons_puts(char*); int cons_puts(char*);
int mknod (char*,short,short,short);
int puts(char*); int puts(char*);
int puts1(char*); int puts1(char*);
char* strcpy(char*, char*); char* strcpy(char*, char*);

View file

@ -1,4 +1,6 @@
#include "user.h" #include "user.h"
#include "types.h"
#include "fs.h"
// file system tests // file system tests
@ -12,6 +14,12 @@ main(void)
puts("userfs running\n"); puts("userfs running\n");
block(); block();
if (mknod ("console", T_DEV, 1, 1) < 0)
puts ("mknod failed\n");
else
puts ("made a node\n");
fd = open("echo", 0); fd = open("echo", 0);
if(fd >= 0){ if(fd >= 0){
puts("open echo ok\n"); puts("open echo ok\n");

1
usys.S
View file

@ -22,3 +22,4 @@ STUB(panic)
STUB(cons_puts) STUB(cons_puts)
STUB(exec) STUB(exec)
STUB(open) STUB(open)
STUB(mknod)