mknod,ialloc,iupdate
This commit is contained in:
parent
104207726b
commit
e8d11c2e84
1
defs.h
1
defs.h
|
@ -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
95
fs.c
|
@ -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
6
fs.h
|
@ -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))
|
||||||
|
|
||||||
|
|
2
fsvar.h
2
fsvar.h
|
@ -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];
|
||||||
|
|
38
syscall.c
38
syscall.c
|
@ -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
|
||||||
|
|
|
@ -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
2
user.h
|
@ -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*);
|
||||||
|
|
8
userfs.c
8
userfs.c
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue