mknod,ialloc,iupdate
This commit is contained in:
parent
104207726b
commit
e8d11c2e84
9 changed files with 152 additions and 2 deletions
1
defs.h
1
defs.h
|
@ -109,3 +109,4 @@ void idecref(struct inode *ip);
|
|||
void iput(struct inode *ip);
|
||||
struct inode * namei(char *path);
|
||||
int readi(struct inode *ip, void *xdst, uint off, uint n);
|
||||
struct inode *mknod(struct inode *, char *, short, short, short);
|
||||
|
|
95
fs.c
95
fs.c
|
@ -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;
|
||||
}
|
||||
|
|
6
fs.h
6
fs.h
|
@ -6,18 +6,22 @@ struct superblock{
|
|||
int ninodes;
|
||||
};
|
||||
|
||||
#define NDIRECT 14
|
||||
#define NDIRECT 13
|
||||
|
||||
// inodes start at the third sector
|
||||
// and blocks start at (ninodes * sizeof(dinode) + 511) / 512
|
||||
struct dinode {
|
||||
short type;
|
||||
short major;
|
||||
short minor;
|
||||
short nlink;
|
||||
uint size;
|
||||
uint addrs[NDIRECT];
|
||||
};
|
||||
|
||||
#define T_DIR 1
|
||||
#define T_FILE 2
|
||||
#define T_DEV 3
|
||||
|
||||
#define IPB (512 / sizeof(struct dinode))
|
||||
|
||||
|
|
2
fsvar.h
2
fsvar.h
|
@ -6,6 +6,8 @@ struct inode {
|
|||
int count;
|
||||
int busy;
|
||||
short type;
|
||||
short major;
|
||||
short minor;
|
||||
short nlink;
|
||||
uint size;
|
||||
uint addrs[NDIRECT];
|
||||
|
|
38
syscall.c
38
syscall.c
|
@ -279,6 +279,41 @@ sys_open(void)
|
|||
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
|
||||
sys_exec(void)
|
||||
{
|
||||
|
@ -515,6 +550,9 @@ syscall(void)
|
|||
case SYS_open:
|
||||
ret = sys_open();
|
||||
break;
|
||||
case SYS_mknod:
|
||||
ret = sys_mknod();
|
||||
break;
|
||||
default:
|
||||
cprintf("unknown sys call %d\n", num);
|
||||
// XXX fault
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
#define SYS_cons_puts 12
|
||||
#define SYS_exec 13
|
||||
#define SYS_open 14
|
||||
#define SYS_mknod 15
|
||||
|
|
2
user.h
2
user.h
|
@ -10,7 +10,7 @@ int block(void);
|
|||
int kill(int);
|
||||
int panic(char*);
|
||||
int cons_puts(char*);
|
||||
|
||||
int mknod (char*,short,short,short);
|
||||
int puts(char*);
|
||||
int puts1(char*);
|
||||
char* strcpy(char*, char*);
|
||||
|
|
8
userfs.c
8
userfs.c
|
@ -1,4 +1,6 @@
|
|||
#include "user.h"
|
||||
#include "types.h"
|
||||
#include "fs.h"
|
||||
|
||||
// file system tests
|
||||
|
||||
|
@ -12,6 +14,12 @@ main(void)
|
|||
|
||||
puts("userfs running\n");
|
||||
block();
|
||||
|
||||
if (mknod ("console", T_DEV, 1, 1) < 0)
|
||||
puts ("mknod failed\n");
|
||||
else
|
||||
puts ("made a node\n");
|
||||
|
||||
fd = open("echo", 0);
|
||||
if(fd >= 0){
|
||||
puts("open echo ok\n");
|
||||
|
|
1
usys.S
1
usys.S
|
@ -22,3 +22,4 @@ STUB(panic)
|
|||
STUB(cons_puts)
|
||||
STUB(exec)
|
||||
STUB(open)
|
||||
STUB(mknod)
|
||||
|
|
Loading…
Reference in a new issue