printf
convert userfs to use printf bfree ifree writei start on unlink
This commit is contained in:
		
							parent
							
								
									939f9edeac
								
							
						
					
					
						commit
						28d9ef04dd
					
				
					 11 changed files with 238 additions and 42 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -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) | ||||
|  |  | |||
|  | @ -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
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								defs.h
									
										
									
									
									
								
							|  | @ -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
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								fd.c
									
										
									
									
									
								
							|  | @ -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
									
										
									
									
									
								
							
							
						
						
									
										97
									
								
								fs.c
									
										
									
									
									
								
							|  | @ -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
									
								
							
							
						
						
									
										76
									
								
								printf.c
									
										
									
									
									
										Normal 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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										27
									
								
								syscall.c
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								syscall.c
									
										
									
									
									
								
							|  | @ -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
 | ||||
|  |  | |||
|  | @ -13,3 +13,5 @@ | |||
| #define SYS_exec 13 | ||||
| #define SYS_open 14 | ||||
| #define SYS_mknod 15 | ||||
| #define SYS_unlink 16 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								user.h
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								user.h
									
										
									
									
									
								
							|  | @ -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, ...); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										58
									
								
								userfs.c
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								userfs.c
									
										
									
									
									
								
							|  | @ -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
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								usys.S
									
										
									
									
									
								
							|  | @ -23,3 +23,4 @@ STUB(cons_puts) | |||
| STUB(exec) | ||||
| STUB(open) | ||||
| STUB(mknod) | ||||
| STUB(unlink)	 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 kaashoek
						kaashoek