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 vectors.S : vectors.pl
perl vectors.pl > vectors.S perl vectors.pl > vectors.S
ULIB = ulib.o usys.o ULIB = ulib.o usys.o printf.o
user1 : user1.o $(ULIB) user1 : user1.o $(ULIB)
$(LD) -N -e main -Ttext 0 -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; int i;
uchar *b = buf; uchar *b = buf;
acquire(&console_lock);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
cons_putc((int) b[i]); cons_putc((int) b[i]);
} }
release(&console_lock);
return n; return n;
} }

2
defs.h
View file

@ -109,5 +109,5 @@ 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);
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); 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){ if(fd->type == FD_PIPE){
return pipe_write(fd->pipe, addr, n); return pipe_write(fd->pipe, addr, n);
} else if (fd->type == FD_FILE) { } 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 { } else {
panic("fd_write"); panic("fd_write");
return -1; return -1;

97
fs.c
View file

@ -23,7 +23,7 @@ balloc(uint dev)
int b; int b;
struct buf *bp; struct buf *bp;
struct superblock *sb; struct superblock *sb;
int bi; int bi = 0;
int size; int size;
int ninodes; int ninodes;
uchar m; uchar m;
@ -50,9 +50,32 @@ balloc(uint dev)
cprintf ("balloc: allocate block %d\n", b); cprintf ("balloc: allocate block %d\n", b);
bp->data[bi/8] |= 0x1 << (bi % 8); bp->data[bi/8] |= 0x1 << (bi % 8);
bwrite (dev, bp, BBLOCK(b, ninodes)); // mark it allocated on disk bwrite (dev, bp, BBLOCK(b, ninodes)); // mark it allocated on disk
brelse(bp);
return b; 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. // returns an inode with busy set and incremented reference count.
struct inode * struct inode *
@ -102,7 +125,24 @@ iget(uint dev, uint inum)
return nip; 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 * struct inode *
ialloc(uint dev, short type) ialloc(uint dev, short type)
{ {
@ -139,21 +179,11 @@ ialloc(uint dev, short type)
return ip; return ip;
} }
void static void
iupdate (struct inode *ip) ifree(uint dev, struct inode *ip)
{ {
struct buf *bp; ip->type = 0;
struct dinode *dip; iupdate(ip);
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);
} }
void void
@ -259,13 +289,44 @@ readi(struct inode *ip, void *xdst, uint off, uint n)
return target - n; return target - n;
} }
#define MIN(a, b) ((a < b) ? a : b)
int 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->type == T_DEV) {
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write) if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
return -1; return -1;
return devsw[ip->major].d_write (ip->minor, addr, n); 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 { } else {
panic ("writei: unknown type\n"); panic ("writei: unknown type\n");
} }
@ -358,7 +419,7 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
} }
brelse(bp); brelse(bp);
} }
panic("mknod: no dir entry free\n"); panic("mknod: XXXX no dir entry free\n");
found: found:
ep->inum = ip->inum; 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; 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 int
sys_exec(void) sys_exec(void)
{ {
@ -561,6 +585,9 @@ syscall(void)
case SYS_mknod: case SYS_mknod:
ret = sys_mknod(); ret = sys_mknod();
break; break;
case SYS_unlink:
ret = sys_unlink();
break;
default: default:
cprintf("unknown sys call %d\n", num); cprintf("unknown sys call %d\n", num);
// XXX fault // XXX fault

View file

@ -13,3 +13,5 @@
#define SYS_exec 13 #define SYS_exec 13
#define SYS_open 14 #define SYS_open 14
#define SYS_mknod 15 #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 exec(char *, char **);
int open(char *, int); int open(char *, int);
int mknod (char*,short,short,short); int mknod (char*,short,short,short);
int unlink (char*);
int puts(char*); int puts(char*);
int puts1(char*); int puts1(char*);
char* strcpy(char*, char*); char* strcpy(char*, char*);
void printf(int fd, char *fmt, ...);

View file

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

1
usys.S
View file

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