convert userfs to use printf
bfree
ifree
writei
start on unlink
This commit is contained in:
kaashoek 2006-08-10 01:28:57 +00:00
parent 939f9edeac
commit 28d9ef04dd
11 changed files with 238 additions and 42 deletions

View file

@ -57,7 +57,7 @@ kernel : $(OBJS) bootother.S user1 usertests userfs
vectors.S : vectors.pl
perl vectors.pl > vectors.S
ULIB = ulib.o usys.o
ULIB = ulib.o usys.o printf.o
user1 : user1.o $(ULIB)
$(LD) -N -e main -Ttext 0 -o user1 user1.o $(ULIB)

View file

@ -163,10 +163,14 @@ console_write (int minor, void *buf, int n)
int i;
uchar *b = buf;
acquire(&console_lock);
for (i = 0; i < n; i++) {
cons_putc((int) b[i]);
}
release(&console_lock);
return n;
}

2
defs.h
View file

@ -109,5 +109,5 @@ 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);
int writei(struct inode *ip, void *addr, uint n);
int writei(struct inode *ip, void *addr, uint off, uint n);
struct inode *mknod(struct inode *, char *, short, short, short);

8
fd.c
View file

@ -59,7 +59,13 @@ fd_write(struct fd *fd, char *addr, int n)
if(fd->type == FD_PIPE){
return pipe_write(fd->pipe, addr, n);
} else if (fd->type == FD_FILE) {
return writei (fd->ip, addr, n);
ilock(fd->ip);
int r = writei (fd->ip, addr, fd->off, n);
if (r > 0) {
fd->off += r;
}
iunlock(fd->ip);
return r;
} else {
panic("fd_write");
return -1;

97
fs.c
View file

@ -23,7 +23,7 @@ balloc(uint dev)
int b;
struct buf *bp;
struct superblock *sb;
int bi;
int bi = 0;
int size;
int ninodes;
uchar m;
@ -50,9 +50,32 @@ balloc(uint dev)
cprintf ("balloc: allocate block %d\n", b);
bp->data[bi/8] |= 0x1 << (bi % 8);
bwrite (dev, bp, BBLOCK(b, ninodes)); // mark it allocated on disk
brelse(bp);
return b;
}
static void
bfree(int dev, uint b)
{
struct buf *bp;
struct superblock *sb;
int bi;
int ninodes;
uchar m;
cprintf ("bfree: free block %d\n", b);
bp = bread(dev, 1);
sb = (struct superblock *) bp->data;
ninodes = sb->ninodes;
brelse(bp);
bp = bread(dev, BBLOCK(b, ninodes));
bi = b % BPB;
m = ~(0x1 << (bi %8));
bp->data[bi/8] &= m;
bwrite (dev, bp, BBLOCK(b, ninodes)); // mark it free on disk
brelse(bp);
}
// returns an inode with busy set and incremented reference count.
struct inode *
@ -102,7 +125,24 @@ iget(uint dev, uint inum)
return nip;
}
// allocate an inode on disk
void
iupdate (struct inode *ip)
{
struct buf *bp;
struct dinode *dip;
bp = bread(ip->dev, IBLOCK(ip->inum));
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;
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
bwrite (ip->dev, bp, IBLOCK(ip->inum)); // mark it allocated on the disk
brelse(bp);
}
struct inode *
ialloc(uint dev, short type)
{
@ -139,21 +179,11 @@ ialloc(uint dev, short type)
return ip;
}
void
iupdate (struct inode *ip)
static void
ifree(uint dev, struct inode *ip)
{
struct buf *bp;
struct dinode *dip;
bp = bread(ip->dev, IBLOCK(ip->inum));
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, IBLOCK(ip->inum)); // mark it allocated on the disk
brelse(bp);
ip->type = 0;
iupdate(ip);
}
void
@ -259,13 +289,44 @@ readi(struct inode *ip, void *xdst, uint off, uint n)
return target - n;
}
#define MIN(a, b) ((a < b) ? a : b)
int
writei(struct inode *ip, void *addr, uint n)
writei(struct inode *ip, void *addr, uint off, uint n)
{
if (ip->type == T_DEV) {
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
return -1;
return devsw[ip->major].d_write (ip->minor, addr, n);
} else if (ip->type == T_FILE || ip->type == T_DIR) { // XXX dir here too?
struct buf *bp;
int r = 0;
int m;
int lbn;
uint b;
while (r < n) {
lbn = off / BSIZE;
if (lbn >= NDIRECT) return r;
if (ip->addrs[lbn] == 0) {
b = balloc(ip->dev);
if (b <= 0) return r;
ip->addrs[lbn] = b;
}
m = MIN(BSIZE - off % BSIZE, n-r);
bp = bread(ip->dev, bmap(ip, off / BSIZE));
memmove (bp->data + off % BSIZE, addr, m);
bwrite (ip->dev, bp, bmap(ip, off/BSIZE));
brelse (bp);
r += m;
off += m;
}
if (r > 0) {
if (off > ip->size) {
ip->size = off;
}
iupdate(ip);
}
return r;
} else {
panic ("writei: unknown type\n");
}
@ -358,7 +419,7 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
}
brelse(bp);
}
panic("mknod: no dir entry free\n");
panic("mknod: XXXX no dir entry free\n");
found:
ep->inum = ip->inum;

76
printf.c Normal file
View file

@ -0,0 +1,76 @@
#include "user.h"
#include "types.h"
static void
putc(int fd, char c)
{
write (fd, &c, 1);
}
static void
printint(int fd, int xx, int base, int sgn)
{
char buf[16];
char digits[] = "0123456789ABCDEF";
int i = 0, neg = 0;
uint x;
if(sgn && xx < 0){
neg = 1;
x = 0 - xx;
} else {
x = xx;
}
do {
buf[i++] = digits[x % base];
} while((x /= base) != 0);
if(neg)
buf[i++] = '-';
while(--i >= 0)
putc(fd, buf[i]);
}
/*
* printf to the stdout. only understands %d, %x, %p, %s.
*/
void
printf(int fd, char *fmt, ...)
{
int i, state = 0, c;
uint *ap = (uint *)(void*)&fmt + 1;
for(i = 0; fmt[i]; i++){
c = fmt[i] & 0xff;
if(state == 0){
if(c == '%'){
state = '%';
} else {
putc(fd, c);
}
} else if(state == '%'){
if(c == 'd'){
printint(fd, *ap, 10, 1);
ap++;
} else if(c == 'x' || c == 'p'){
printint(fd, *ap, 16, 0);
ap++;
} else if(c == 's'){
char *s = (char*)*ap;
ap++;
while(*s != 0){
putc(fd, *s);
s++;
}
} else if(c == '%'){
putc(fd, c);
} else {
// Unknown % sequence. Print it to draw attention.
putc(fd, '%');
putc(fd, c);
}
state = 0;
}
}
}

View file

@ -330,6 +330,30 @@ sys_mknod(void)
return 0;
}
int
sys_unlink(void)
{
struct proc *cp = curproc[cpu()];
struct inode *ip;
uint arg0;
if(fetcharg(0, &arg0) < 0)
return -1;
if(checkstring(arg0) < 0)
return -1;
ip = namei(cp->mem + arg0);
ip->nlink--;
if (ip->nlink <= 0) {
panic("sys_link: unimplemented\n");
}
iupdate(ip);
iput(ip);
return 0;
}
int
sys_exec(void)
{
@ -561,6 +585,9 @@ syscall(void)
case SYS_mknod:
ret = sys_mknod();
break;
case SYS_unlink:
ret = sys_unlink();
break;
default:
cprintf("unknown sys call %d\n", num);
// XXX fault

View file

@ -13,3 +13,5 @@
#define SYS_exec 13
#define SYS_open 14
#define SYS_mknod 15
#define SYS_unlink 16

3
user.h
View file

@ -13,6 +13,9 @@ int cons_puts(char*);
int exec(char *, char **);
int open(char *, int);
int mknod (char*,short,short,short);
int unlink (char*);
int puts(char*);
int puts1(char*);
char* strcpy(char*, char*);
void printf(int fd, char *fmt, ...);

View file

@ -4,7 +4,7 @@
// file system tests
char buf[1024];
char buf[2000];
char *echo_args[] = { "echo", "hello", "goodbye", 0 };
char *cat_args[] = { "cat", "README", 0 };
@ -12,48 +12,64 @@ int
main(void)
{
int fd;
int i;
int stdout;
puts("userfs running\n");
block();
// printf(stdout, "userfs running\n");
if (mknod ("console", T_DEV, 1, 1) < 0)
puts ("mknod failed\n");
else
puts ("made a node\n");
fd = open("console", O_WRONLY);
if(fd >= 0){
puts("open console ok\n");
} else {
puts("open console failed!\n");
}
if (write (fd, "hello\n", 6) != 6) {
puts ("write to console failed\n");
}
close (fd);
stdout = open("console", O_WRONLY);
printf(stdout, "userfs is running\n");
block();
fd = open("echo", 0);
if(fd >= 0){
puts("open echo ok\n");
printf(stdout, "open echo ok\n");
close(fd);
} else {
puts("open echo failed!\n");
printf(stdout, "open echo failed!\n");
}
fd = open("doesnotexist", 0);
if(fd >= 0){
puts("open doesnotexist succeeded!\n");
printf(stdout, "open doesnotexist succeeded!\n");
close(fd);
} else {
puts("open doesnotexist failed\n");
printf(stdout, "open doesnotexist failed\n");
}
fd = open("doesnotexist", O_CREATE|O_RDWR);
if(fd >= 0){
puts("creat doesnotexist succeeded\n");
printf(stdout, "creat doesnotexist succeeded\n");
} else {
puts("error: creat doesnotexist failed!\n");
printf(stdout, "error: creat doesnotexist failed!\n");
}
for (i = 0; i < 100; i++) {
if (write (fd, "aaaaaaaaaa", 10) != 10) {
printf(stdout, "error: write new file failed\n");
}
if (write (fd, "bbbbbbbbbb", 10) != 10) {
printf(stdout, "error: write new file failed\n");
}
}
printf(stdout, "writes done\n");
close(fd);
fd = open("doesnotexist", O_RDONLY);
if(fd >= 0){
printf(stdout, "open doesnotexist succeeded\n");
} else {
printf(stdout, "error: open doesnotexist failed!\n");
}
i = read(fd, buf, 10000);
if (i == 2000) {
printf(stdout, "read succeeded\\n");
} else {
printf(stdout, "read failed\n");
}
close(fd);
//exec("echo", echo_args);
printf(stdout, "about to do exec\n");
exec("cat", cat_args);
return 0;
}

1
usys.S
View file

@ -23,3 +23,4 @@ STUB(cons_puts)
STUB(exec)
STUB(open)
STUB(mknod)
STUB(unlink)