support read() and write() bigger than one page
This commit is contained in:
		
							parent
							
								
									cefe223bf5
								
							
						
					
					
						commit
						8baac76050
					
				
					 12 changed files with 95 additions and 62 deletions
				
			
		
							
								
								
									
										18
									
								
								console.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								console.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -155,10 +155,11 @@ struct {
 | 
			
		|||
#define C(x)  ((x)-'@')  // Contro
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
consoleread(struct inode *ip, char *dst, int n)
 | 
			
		||||
consoleread(struct inode *ip, int user_dst, uint64 dst, int n)
 | 
			
		||||
{
 | 
			
		||||
  uint target;
 | 
			
		||||
  int c;
 | 
			
		||||
  char buf[1];
 | 
			
		||||
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  target = n;
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +182,10 @@ consoleread(struct inode *ip, char *dst, int n)
 | 
			
		|||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    *dst++ = c;
 | 
			
		||||
    buf[0] = c;
 | 
			
		||||
    if(either_copyout(user_dst, dst, &buf[0], 1) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
    dst++;
 | 
			
		||||
    --n;
 | 
			
		||||
    if(c == '\n')
 | 
			
		||||
      break;
 | 
			
		||||
| 
						 | 
				
			
			@ -193,14 +197,18 @@ consoleread(struct inode *ip, char *dst, int n)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
consolewrite(struct inode *ip, char *buf, int n)
 | 
			
		||||
consolewrite(struct inode *ip, int user_src, uint64 src, int n)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  acquire(&cons.lock);
 | 
			
		||||
  for(i = 0; i < n; i++)
 | 
			
		||||
    consputc(buf[i] & 0xff);
 | 
			
		||||
  for(i = 0; i < n; i++){
 | 
			
		||||
    char c;
 | 
			
		||||
    if(either_copyin(&c, user_src, src, 1) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
    consputc(c);
 | 
			
		||||
  }
 | 
			
		||||
  release(&cons.lock);
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								defs.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -50,9 +50,9 @@ void            iupdate(struct inode*);
 | 
			
		|||
int             namecmp(const char*, const char*);
 | 
			
		||||
struct inode*   namei(char*);
 | 
			
		||||
struct inode*   nameiparent(char*, char*);
 | 
			
		||||
int             readi(struct inode*, char*, uint, uint);
 | 
			
		||||
int             readi(struct inode*, int, uint64, uint, uint);
 | 
			
		||||
void            stati(struct inode*, struct stat*);
 | 
			
		||||
int             writei(struct inode*, char*, uint, uint);
 | 
			
		||||
int             writei(struct inode*, int, uint64, uint, uint);
 | 
			
		||||
 | 
			
		||||
// ramdisk.c
 | 
			
		||||
void            ramdiskinit(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,8 +98,8 @@ void            picinit(void);
 | 
			
		|||
// pipe.c
 | 
			
		||||
int             pipealloc(struct file**, struct file**);
 | 
			
		||||
void            pipeclose(struct pipe*, int);
 | 
			
		||||
int             piperead(struct pipe*, char*, int);
 | 
			
		||||
int             pipewrite(struct pipe*, char*, int);
 | 
			
		||||
int             piperead(struct pipe*, uint64, int);
 | 
			
		||||
int             pipewrite(struct pipe*, uint64, int);
 | 
			
		||||
 | 
			
		||||
//PAGEBREAK: 16
 | 
			
		||||
// proc.c
 | 
			
		||||
| 
						 | 
				
			
			@ -122,6 +122,8 @@ void            userinit(void);
 | 
			
		|||
int             wait(void);
 | 
			
		||||
void            wakeup(void*);
 | 
			
		||||
void            yield(void);
 | 
			
		||||
int             either_copyout(int user_dst, uint64 dst, char *src, uint64 len);
 | 
			
		||||
int             either_copyin(char *dst, int user_src, uint64 src, uint64 len);
 | 
			
		||||
 | 
			
		||||
// swtch.S
 | 
			
		||||
void            swtch(struct context*, struct context*);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								exec.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								exec.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -30,7 +30,7 @@ exec(char *path, char **argv)
 | 
			
		|||
  ilock(ip);
 | 
			
		||||
 | 
			
		||||
  // Check ELF header
 | 
			
		||||
  if(readi(ip, (char*)&elf, 0, sizeof(elf)) != sizeof(elf))
 | 
			
		||||
  if(readi(ip, 0, (uint64)&elf, 0, sizeof(elf)) != sizeof(elf))
 | 
			
		||||
    goto bad;
 | 
			
		||||
  if(elf.magic != ELF_MAGIC)
 | 
			
		||||
    goto bad;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ exec(char *path, char **argv)
 | 
			
		|||
  // Load program into memory.
 | 
			
		||||
  sz = 0;
 | 
			
		||||
  for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
 | 
			
		||||
    if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
 | 
			
		||||
    if(readi(ip, 0, (uint64)&ph, off, sizeof(ph)) != sizeof(ph))
 | 
			
		||||
      goto bad;
 | 
			
		||||
    if(ph.type != ELF_PROG_LOAD)
 | 
			
		||||
      continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +128,7 @@ loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz
 | 
			
		|||
 | 
			
		||||
  if((va % PGSIZE) != 0)
 | 
			
		||||
    panic("loadseg: va must be page aligned");
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < sz; i += PGSIZE){
 | 
			
		||||
    pa = walkaddr(pagetable, va + i);
 | 
			
		||||
    if(pa == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -136,8 +137,9 @@ loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz
 | 
			
		|||
      n = sz - i;
 | 
			
		||||
    else
 | 
			
		||||
      n = PGSIZE;
 | 
			
		||||
    if(readi(ip, (char *)pa, offset+i, n) != n)
 | 
			
		||||
    if(readi(ip, 0, (uint64)pa, offset+i, n) != n)
 | 
			
		||||
      return -1;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								file.c
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								file.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -113,33 +113,17 @@ fileread(struct file *f, uint64 addr, int n)
 | 
			
		|||
  if(f->readable == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  // XXX break into page-size pieces.
 | 
			
		||||
  if(n > PGSIZE)
 | 
			
		||||
    panic("fileread PGSIZE");
 | 
			
		||||
 | 
			
		||||
  buf = kalloc();
 | 
			
		||||
  if(buf == 0)
 | 
			
		||||
    panic("fileread kalloc");
 | 
			
		||||
 | 
			
		||||
  if(f->type == FD_PIPE){
 | 
			
		||||
    r = piperead(f->pipe, buf, n);
 | 
			
		||||
    r = piperead(f->pipe, addr, n);
 | 
			
		||||
  } else if(f->type == FD_INODE){
 | 
			
		||||
    ilock(f->ip);
 | 
			
		||||
    if((r = readi(f->ip, buf, f->off, n)) > 0)
 | 
			
		||||
    if((r = readi(f->ip, 1, addr, f->off, n)) > 0)
 | 
			
		||||
      f->off += r;
 | 
			
		||||
    iunlock(f->ip);
 | 
			
		||||
  } else {
 | 
			
		||||
    panic("fileread");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(r > 0){
 | 
			
		||||
    if(copyout(p->pagetable, addr, buf, n) < 0){
 | 
			
		||||
      r = -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  kfree(buf);
 | 
			
		||||
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -156,18 +140,8 @@ filewrite(struct file *f, uint64 addr, int n)
 | 
			
		|||
  if(f->writable == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  // XXX break into pieces
 | 
			
		||||
  if(n > PGSIZE)
 | 
			
		||||
    panic("filewrite PGSIZE");
 | 
			
		||||
 | 
			
		||||
  buf = kalloc();
 | 
			
		||||
  if(copyin(p->pagetable, buf, addr, n) < 0){
 | 
			
		||||
    kfree(buf);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(f->type == FD_PIPE){
 | 
			
		||||
    ret = pipewrite(f->pipe, buf, n);
 | 
			
		||||
    ret = pipewrite(f->pipe, addr, n);
 | 
			
		||||
  } else if(f->type == FD_INODE){
 | 
			
		||||
    // write a few blocks at a time to avoid exceeding
 | 
			
		||||
    // the maximum log transaction size, including
 | 
			
		||||
| 
						 | 
				
			
			@ -184,7 +158,7 @@ filewrite(struct file *f, uint64 addr, int n)
 | 
			
		|||
 | 
			
		||||
      begin_op();
 | 
			
		||||
      ilock(f->ip);
 | 
			
		||||
      if ((r = writei(f->ip, buf + i, f->off, n1)) > 0)
 | 
			
		||||
      if ((r = writei(f->ip, 1, addr + i, f->off, n1)) > 0)
 | 
			
		||||
        f->off += r;
 | 
			
		||||
      iunlock(f->ip);
 | 
			
		||||
      end_op();
 | 
			
		||||
| 
						 | 
				
			
			@ -200,8 +174,6 @@ filewrite(struct file *f, uint64 addr, int n)
 | 
			
		|||
    panic("filewrite");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  kfree(buf);
 | 
			
		||||
  
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								file.h
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								file.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -28,8 +28,8 @@ struct inode {
 | 
			
		|||
// table mapping major device number to
 | 
			
		||||
// device functions
 | 
			
		||||
struct devsw {
 | 
			
		||||
  int (*read)(struct inode*, char*, int);
 | 
			
		||||
  int (*write)(struct inode*, char*, int);
 | 
			
		||||
  int (*read)(struct inode*, int, uint64, int);
 | 
			
		||||
  int (*write)(struct inode*, int, uint64, int);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern struct devsw devsw[];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								fs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -180,6 +180,8 @@ iinit(int dev)
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  readsb(dev, &sb);
 | 
			
		||||
  if(sb.magic != FSMAGIC)
 | 
			
		||||
    panic("invalid file system");
 | 
			
		||||
  printf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\
 | 
			
		||||
 inodestart %d bmap start %d\n", sb.size, sb.nblocks,
 | 
			
		||||
          sb.ninodes, sb.nlog, sb.logstart, sb.inodestart,
 | 
			
		||||
| 
						 | 
				
			
			@ -450,8 +452,10 @@ stati(struct inode *ip, struct stat *st)
 | 
			
		|||
//PAGEBREAK!
 | 
			
		||||
// Read data from inode.
 | 
			
		||||
// Caller must hold ip->lock.
 | 
			
		||||
// If user_dst==1, then dst is a user virtual address;
 | 
			
		||||
// otherwise, dst is a kernel address.
 | 
			
		||||
int
 | 
			
		||||
readi(struct inode *ip, char *dst, uint off, uint n)
 | 
			
		||||
readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
 | 
			
		||||
{
 | 
			
		||||
  uint tot, m;
 | 
			
		||||
  struct buf *bp;
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +463,7 @@ readi(struct inode *ip, char *dst, uint off, uint n)
 | 
			
		|||
  if(ip->type == T_DEV){
 | 
			
		||||
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read)
 | 
			
		||||
      return -1;
 | 
			
		||||
    return devsw[ip->major].read(ip, dst, n);
 | 
			
		||||
    return devsw[ip->major].read(ip, user_dst, dst, n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(off > ip->size || off + n < off)
 | 
			
		||||
| 
						 | 
				
			
			@ -470,7 +474,8 @@ readi(struct inode *ip, char *dst, uint off, uint n)
 | 
			
		|||
  for(tot=0; tot<n; tot+=m, off+=m, dst+=m){
 | 
			
		||||
    bp = bread(ip->dev, bmap(ip, off/BSIZE));
 | 
			
		||||
    m = min(n - tot, BSIZE - off%BSIZE);
 | 
			
		||||
    memmove(dst, bp->data + off%BSIZE, m);
 | 
			
		||||
    if(either_copyout(user_dst, dst, bp->data + (off % BSIZE), m) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
    brelse(bp);
 | 
			
		||||
  }
 | 
			
		||||
  return n;
 | 
			
		||||
| 
						 | 
				
			
			@ -479,8 +484,10 @@ readi(struct inode *ip, char *dst, uint off, uint n)
 | 
			
		|||
// PAGEBREAK!
 | 
			
		||||
// Write data to inode.
 | 
			
		||||
// Caller must hold ip->lock.
 | 
			
		||||
// If user_src==1, then src is a user virtual address;
 | 
			
		||||
// otherwise, src is a kernel address.
 | 
			
		||||
int
 | 
			
		||||
writei(struct inode *ip, char *src, uint off, uint n)
 | 
			
		||||
writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
 | 
			
		||||
{
 | 
			
		||||
  uint tot, m;
 | 
			
		||||
  struct buf *bp;
 | 
			
		||||
| 
						 | 
				
			
			@ -489,7 +496,7 @@ writei(struct inode *ip, char *src, uint off, uint n)
 | 
			
		|||
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write){
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
    return devsw[ip->major].write(ip, src, n);
 | 
			
		||||
    return devsw[ip->major].write(ip, user_src, src, n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(off > ip->size || off + n < off)
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +507,8 @@ writei(struct inode *ip, char *src, uint off, uint n)
 | 
			
		|||
  for(tot=0; tot<n; tot+=m, off+=m, src+=m){
 | 
			
		||||
    bp = bread(ip->dev, bmap(ip, off/BSIZE));
 | 
			
		||||
    m = min(n - tot, BSIZE - off%BSIZE);
 | 
			
		||||
    memmove(bp->data + off%BSIZE, src, m);
 | 
			
		||||
    if(either_copyin(bp->data + (off % BSIZE), user_src, src, m) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
    log_write(bp);
 | 
			
		||||
    brelse(bp);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -533,7 +541,7 @@ dirlookup(struct inode *dp, char *name, uint *poff)
 | 
			
		|||
    panic("dirlookup not DIR");
 | 
			
		||||
 | 
			
		||||
  for(off = 0; off < dp->size; off += sizeof(de)){
 | 
			
		||||
    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
    if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
      panic("dirlookup read");
 | 
			
		||||
    if(de.inum == 0)
 | 
			
		||||
      continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -565,7 +573,7 @@ dirlink(struct inode *dp, char *name, uint inum)
 | 
			
		|||
 | 
			
		||||
  // Look for an empty dirent.
 | 
			
		||||
  for(off = 0; off < dp->size; off += sizeof(de)){
 | 
			
		||||
    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
    if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
      panic("dirlink read");
 | 
			
		||||
    if(de.inum == 0)
 | 
			
		||||
      break;
 | 
			
		||||
| 
						 | 
				
			
			@ -573,7 +581,7 @@ dirlink(struct inode *dp, char *name, uint inum)
 | 
			
		|||
 | 
			
		||||
  strncpy(de.name, name, DIRSIZ);
 | 
			
		||||
  de.inum = inum;
 | 
			
		||||
  if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
  if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
    panic("dirlink");
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								fs.h
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								fs.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
// mkfs computes the super block and builds an initial file system. The
 | 
			
		||||
// super block describes the disk layout:
 | 
			
		||||
struct superblock {
 | 
			
		||||
  uint magic;        // Must be FSMAGIC
 | 
			
		||||
  uint size;         // Size of file system image (blocks)
 | 
			
		||||
  uint nblocks;      // Number of data blocks
 | 
			
		||||
  uint ninodes;      // Number of inodes.
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +22,8 @@ struct superblock {
 | 
			
		|||
  uint bmapstart;    // Block number of first free map block
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FSMAGIC 0x10203040
 | 
			
		||||
 | 
			
		||||
#define NDIRECT 12
 | 
			
		||||
#define NINDIRECT (BSIZE / sizeof(uint))
 | 
			
		||||
#define MAXFILE (NDIRECT + NINDIRECT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								mkfs.c
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								mkfs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -94,6 +94,7 @@ main(int argc, char *argv[])
 | 
			
		|||
  nmeta = 2 + nlog + ninodeblocks + nbitmap;
 | 
			
		||||
  nblocks = FSSIZE - nmeta;
 | 
			
		||||
 | 
			
		||||
  sb.magic = FSMAGIC;
 | 
			
		||||
  sb.size = xint(FSSIZE);
 | 
			
		||||
  sb.nblocks = xint(nblocks);
 | 
			
		||||
  sb.ninodes = xint(NINODES);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								pipe.c
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								pipe.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -76,9 +76,11 @@ pipeclose(struct pipe *p, int writable)
 | 
			
		|||
 | 
			
		||||
//PAGEBREAK: 40
 | 
			
		||||
int
 | 
			
		||||
pipewrite(struct pipe *p, char *addr, int n)
 | 
			
		||||
pipewrite(struct pipe *p, uint64 addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  char ch;
 | 
			
		||||
  struct proc *pr = myproc();
 | 
			
		||||
 | 
			
		||||
  acquire(&p->lock);
 | 
			
		||||
  for(i = 0; i < n; i++){
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +92,9 @@ pipewrite(struct pipe *p, char *addr, int n)
 | 
			
		|||
      wakeup(&p->nread);
 | 
			
		||||
      sleep(&p->nwrite, &p->lock);  //DOC: pipewrite-sleep
 | 
			
		||||
    }
 | 
			
		||||
    p->data[p->nwrite++ % PIPESIZE] = addr[i];
 | 
			
		||||
    if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
    p->data[p->nwrite++ % PIPESIZE] = ch;
 | 
			
		||||
  }
 | 
			
		||||
  wakeup(&p->nread);  //DOC: pipewrite-wakeup1
 | 
			
		||||
  release(&p->lock);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,9 +102,11 @@ pipewrite(struct pipe *p, char *addr, int n)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
piperead(struct pipe *p, char *addr, int n)
 | 
			
		||||
piperead(struct pipe *p, uint64 addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  struct proc *pr = myproc();
 | 
			
		||||
  char ch;
 | 
			
		||||
 | 
			
		||||
  acquire(&p->lock);
 | 
			
		||||
  while(p->nread == p->nwrite && p->writeopen){  //DOC: pipe-empty
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +119,9 @@ piperead(struct pipe *p, char *addr, int n)
 | 
			
		|||
  for(i = 0; i < n; i++){  //DOC: piperead-copy
 | 
			
		||||
    if(p->nread == p->nwrite)
 | 
			
		||||
      break;
 | 
			
		||||
    addr[i] = p->data[p->nread++ % PIPESIZE];
 | 
			
		||||
    ch = p->data[p->nread++ % PIPESIZE];
 | 
			
		||||
    if(copyout(pr->pagetable, addr + i, &ch, 1) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  wakeup(&p->nwrite);  //DOC: piperead-wakeup
 | 
			
		||||
  release(&p->lock);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -526,3 +526,32 @@ kill(int pid)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Copy to either a user address, or kernel address,
 | 
			
		||||
// depending on usr_dst.
 | 
			
		||||
// Returns 0 on success, -1 on error.
 | 
			
		||||
int
 | 
			
		||||
either_copyout(int user_dst, uint64 dst, char *src, uint64 len)
 | 
			
		||||
{
 | 
			
		||||
  struct proc *p = myproc();
 | 
			
		||||
  if(user_dst){
 | 
			
		||||
    return copyout(p->pagetable, dst, src, len);
 | 
			
		||||
  } else {
 | 
			
		||||
    memmove((char *)dst, src, len);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Copy from either a user address, or kernel address,
 | 
			
		||||
// depending on usr_src.
 | 
			
		||||
// Returns 0 on success, -1 on error.
 | 
			
		||||
int
 | 
			
		||||
either_copyin(char *dst, int user_src, uint64 src, uint64 len)
 | 
			
		||||
{
 | 
			
		||||
  struct proc *p = myproc();
 | 
			
		||||
  if(user_src){
 | 
			
		||||
    return copyin(p->pagetable, dst, src, len);
 | 
			
		||||
  } else {
 | 
			
		||||
    memmove(dst, (char*)src, len);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ isdirempty(struct inode *dp)
 | 
			
		|||
  struct dirent de;
 | 
			
		||||
 | 
			
		||||
  for(off=2*sizeof(de); off<dp->size; off+=sizeof(de)){
 | 
			
		||||
    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
    if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
      panic("isdirempty: readi");
 | 
			
		||||
    if(de.inum != 0)
 | 
			
		||||
      return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +217,7 @@ sys_unlink(void)
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  memset(&de, 0, sizeof(de));
 | 
			
		||||
  if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
  if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
    panic("unlink: writei");
 | 
			
		||||
  if(ip->type == T_DIR){
 | 
			
		||||
    dp->nlink--;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								vm.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -342,7 +342,7 @@ copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
 | 
			
		|||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Copy a null-terminated from user to kernel.
 | 
			
		||||
// Copy a null-terminated string from user to kernel.
 | 
			
		||||
// Copy bytes to dst from virtual address srcva in a given page table,
 | 
			
		||||
// until a '\0', or max.
 | 
			
		||||
// Return 0 on success, -1 on error.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue