Remove struct uinode.
Remove type arg to mknod (assume T_DEV).
This commit is contained in:
		
							parent
							
								
									fa1b34106a
								
							
						
					
					
						commit
						07090dd705
					
				
					 10 changed files with 129 additions and 140 deletions
				
			
		
							
								
								
									
										18
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								defs.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,7 +6,6 @@ struct pipe;
 | 
			
		|||
struct proc;
 | 
			
		||||
struct spinlock;
 | 
			
		||||
struct stat;
 | 
			
		||||
struct uinode;
 | 
			
		||||
 | 
			
		||||
// 8253pit.c
 | 
			
		||||
void            pit8253_timerinit(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -37,17 +36,18 @@ int             filewrite(struct file*, char*, int n);
 | 
			
		|||
 | 
			
		||||
// fs.c
 | 
			
		||||
int             dirlink(struct inode*, char*, uint);
 | 
			
		||||
struct uinode*  dirlookup(struct inode*, char*, uint*);
 | 
			
		||||
struct uinode*  ialloc(uint, short);
 | 
			
		||||
struct uinode*  idup(struct uinode*);
 | 
			
		||||
struct inode*   dirlookup(struct inode*, char*, uint*);
 | 
			
		||||
struct inode*   ialloc(uint, short);
 | 
			
		||||
struct inode*   idup(struct inode*);
 | 
			
		||||
void            iinit(void);
 | 
			
		||||
struct inode*   ilock(struct uinode*);
 | 
			
		||||
struct uinode*  iunlock(struct inode*);
 | 
			
		||||
void            iput(struct uinode*);
 | 
			
		||||
void            ilock(struct inode*);
 | 
			
		||||
void            iput(struct inode*);
 | 
			
		||||
void            iunlock(struct inode*);
 | 
			
		||||
void            iunlockput(struct inode*);
 | 
			
		||||
void            iupdate(struct inode*);
 | 
			
		||||
int             namecmp(const char*, const char*);
 | 
			
		||||
struct uinode*  namei(char*);
 | 
			
		||||
struct uinode*  nameiparent(char*, char*);
 | 
			
		||||
struct inode*   namei(char*);
 | 
			
		||||
struct inode*   nameiparent(char*, char*);
 | 
			
		||||
int             readi(struct inode*, char*, uint, uint);
 | 
			
		||||
void            stati(struct inode*, struct stat*);
 | 
			
		||||
int             writei(struct inode*, char*, uint, uint);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								exec.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								exec.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -29,8 +29,9 @@ exec(char *path, char **argv)
 | 
			
		|||
  sz = 0;
 | 
			
		||||
  mem = 0;
 | 
			
		||||
 | 
			
		||||
  if((ip = ilock(namei(path))) == 0)
 | 
			
		||||
  if((ip = namei(path)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
 | 
			
		||||
  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
 | 
			
		||||
    goto bad;
 | 
			
		||||
| 
						 | 
				
			
			@ -112,8 +113,7 @@ exec(char *path, char **argv)
 | 
			
		|||
      goto bad2;
 | 
			
		||||
    memset(cp->mem + ph.va + ph.filesz, 0, ph.memsz - ph.filesz);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iput(iunlock(ip));
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  
 | 
			
		||||
  cp->tf->eip = elf.entry;
 | 
			
		||||
  cp->tf->esp = sp;
 | 
			
		||||
| 
						 | 
				
			
			@ -124,11 +124,11 @@ exec(char *path, char **argv)
 | 
			
		|||
 bad:
 | 
			
		||||
  if(mem)
 | 
			
		||||
    kfree(mem, sz);
 | 
			
		||||
  iput(iunlock(ip));
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  return -1;
 | 
			
		||||
 | 
			
		||||
 bad2:
 | 
			
		||||
  iput(iunlock(ip));
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  proc_exit();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								file.c
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								file.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -56,17 +56,16 @@ int
 | 
			
		|||
fileread(struct file *f, char *addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  int r;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  if(f->readable == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(f->type == FD_PIPE)
 | 
			
		||||
    return pipe_read(f->pipe, addr, n);
 | 
			
		||||
  if(f->type == FD_INODE){
 | 
			
		||||
    ip = ilock(f->ip);
 | 
			
		||||
    if((r = readi(ip, addr, f->off, n)) > 0)
 | 
			
		||||
    ilock(f->ip);
 | 
			
		||||
    if((r = readi(f->ip, addr, f->off, n)) > 0)
 | 
			
		||||
      f->off += r;
 | 
			
		||||
    iunlock(ip);
 | 
			
		||||
    iunlock(f->ip);
 | 
			
		||||
    return r;
 | 
			
		||||
  }
 | 
			
		||||
  panic("fileread");
 | 
			
		||||
| 
						 | 
				
			
			@ -77,17 +76,16 @@ int
 | 
			
		|||
filewrite(struct file *f, char *addr, int n)
 | 
			
		||||
{
 | 
			
		||||
  int r;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  if(f->writable == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if(f->type == FD_PIPE)
 | 
			
		||||
    return pipe_write(f->pipe, addr, n);
 | 
			
		||||
  if(f->type == FD_INODE){
 | 
			
		||||
    ip = ilock(f->ip);
 | 
			
		||||
    if((r = writei(ip, addr, f->off, n)) > 0)
 | 
			
		||||
    ilock(f->ip);
 | 
			
		||||
    if((r = writei(f->ip, addr, f->off, n)) > 0)
 | 
			
		||||
      f->off += r;
 | 
			
		||||
    iunlock(ip);
 | 
			
		||||
    iunlock(f->ip);
 | 
			
		||||
    return r;
 | 
			
		||||
  }
 | 
			
		||||
  panic("filewrite");
 | 
			
		||||
| 
						 | 
				
			
			@ -97,12 +95,10 @@ filewrite(struct file *f, char *addr, int n)
 | 
			
		|||
int
 | 
			
		||||
filestat(struct file *f, struct stat *st)
 | 
			
		||||
{
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  if(f->type == FD_INODE){
 | 
			
		||||
    ip = ilock(f->ip);
 | 
			
		||||
    stati(ip, st);
 | 
			
		||||
    iunlock(ip);
 | 
			
		||||
    ilock(f->ip);
 | 
			
		||||
    stati(f->ip, st);
 | 
			
		||||
    iunlock(f->ip);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								file.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								file.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4,6 +4,6 @@ struct file {
 | 
			
		|||
  char readable;
 | 
			
		||||
  char writable;
 | 
			
		||||
  struct pipe *pipe;
 | 
			
		||||
  struct uinode *ip;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
  uint off;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										94
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										94
									
								
								fs.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -129,7 +129,7 @@ iinit(void)
 | 
			
		|||
 | 
			
		||||
// Find the inode with number inum on device dev
 | 
			
		||||
// and return the in-memory copy. h
 | 
			
		||||
static struct uinode*
 | 
			
		||||
static struct inode*
 | 
			
		||||
iget(uint dev, uint inum)
 | 
			
		||||
{
 | 
			
		||||
  struct inode *ip, *empty;
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@ iget(uint dev, uint inum)
 | 
			
		|||
    if(ip->ref > 0 && ip->dev == dev && ip->inum == inum){
 | 
			
		||||
      ip->ref++;
 | 
			
		||||
      release(&icache.lock);
 | 
			
		||||
      return (struct uinode*)ip;
 | 
			
		||||
      return ip;
 | 
			
		||||
    }
 | 
			
		||||
    if(empty == 0 && ip->ref == 0)    // Remember empty slot.
 | 
			
		||||
      empty = ip;
 | 
			
		||||
| 
						 | 
				
			
			@ -159,37 +159,29 @@ iget(uint dev, uint inum)
 | 
			
		|||
  ip->flags = 0;
 | 
			
		||||
  release(&icache.lock);
 | 
			
		||||
 | 
			
		||||
  return (struct uinode*)ip;
 | 
			
		||||
  return ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Increment reference count for ip.
 | 
			
		||||
// Returns ip to enable ip = idup(ip1) idiom.
 | 
			
		||||
struct uinode*
 | 
			
		||||
idup(struct uinode *uip)
 | 
			
		||||
struct inode*
 | 
			
		||||
idup(struct inode *ip)
 | 
			
		||||
{
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  ip = (struct inode*)uip;
 | 
			
		||||
  acquire(&icache.lock);
 | 
			
		||||
  ip->ref++;
 | 
			
		||||
  release(&icache.lock);
 | 
			
		||||
  return uip;
 | 
			
		||||
  return ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Lock the given inode.
 | 
			
		||||
struct inode*
 | 
			
		||||
ilock(struct uinode *uip)
 | 
			
		||||
void
 | 
			
		||||
ilock(struct inode *ip)
 | 
			
		||||
{
 | 
			
		||||
  struct buf *bp;
 | 
			
		||||
  struct dinode *dip;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  ip = (struct inode*)uip;
 | 
			
		||||
  if(ip == 0)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  if(ip->ref < 1)
 | 
			
		||||
    panic("ilock: no refs");
 | 
			
		||||
  if(ip == 0 || ip->ref < 1)
 | 
			
		||||
    panic("ilock");
 | 
			
		||||
 | 
			
		||||
  acquire(&icache.lock);
 | 
			
		||||
  while(ip->flags & I_BUSY)
 | 
			
		||||
| 
						 | 
				
			
			@ -211,33 +203,25 @@ ilock(struct uinode *uip)
 | 
			
		|||
    if(ip->type == 0)
 | 
			
		||||
      panic("ilock: no type");
 | 
			
		||||
  }
 | 
			
		||||
  return ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unlock the given inode.
 | 
			
		||||
struct uinode*
 | 
			
		||||
void
 | 
			
		||||
iunlock(struct inode *ip)
 | 
			
		||||
{
 | 
			
		||||
  if(ip == 0)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  if(!(ip->flags & I_BUSY) || ip->ref < 1)
 | 
			
		||||
  if(ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1)
 | 
			
		||||
    panic("iunlock");
 | 
			
		||||
 | 
			
		||||
  acquire(&icache.lock);
 | 
			
		||||
  ip->flags &= ~I_BUSY;
 | 
			
		||||
  wakeup(ip);
 | 
			
		||||
  release(&icache.lock);
 | 
			
		||||
  return (struct uinode*)ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Caller holds reference to unlocked ip.  Drop reference.
 | 
			
		||||
void
 | 
			
		||||
iput(struct uinode *uip)
 | 
			
		||||
iput(struct inode *ip)
 | 
			
		||||
{
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
  
 | 
			
		||||
  ip = (struct inode*)uip;
 | 
			
		||||
  acquire(&icache.lock);
 | 
			
		||||
  if(ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0) {
 | 
			
		||||
    // inode is no longer used: truncate and free inode.
 | 
			
		||||
| 
						 | 
				
			
			@ -256,8 +240,15 @@ iput(struct uinode *uip)
 | 
			
		|||
  release(&icache.lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
iunlockput(struct inode *ip)
 | 
			
		||||
{
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  iput(ip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Allocate a new inode with the given type on device dev.
 | 
			
		||||
struct uinode*
 | 
			
		||||
struct inode*
 | 
			
		||||
ialloc(uint dev, short type)
 | 
			
		||||
{
 | 
			
		||||
  int inum, ninodes;
 | 
			
		||||
| 
						 | 
				
			
			@ -478,7 +469,7 @@ namecmp(const char *s, const char *t)
 | 
			
		|||
// Look for a directory entry in a directory.
 | 
			
		||||
// If found, set *poff to byte offset of entry.
 | 
			
		||||
// Caller must have already locked dp.
 | 
			
		||||
struct uinode*
 | 
			
		||||
struct inode*
 | 
			
		||||
dirlookup(struct inode *dp, char *name, uint *poff)
 | 
			
		||||
{
 | 
			
		||||
  uint off, inum;
 | 
			
		||||
| 
						 | 
				
			
			@ -527,11 +518,11 @@ dirlink(struct inode *dp, char *name, uint ino)
 | 
			
		|||
{
 | 
			
		||||
  int off;
 | 
			
		||||
  struct dirent de;
 | 
			
		||||
  struct uinode *ipu;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  // Check that name is not present.
 | 
			
		||||
  if((ipu = dirlookup(dp, name, 0)) != 0){
 | 
			
		||||
    iput(ipu);
 | 
			
		||||
  if((ip = dirlookup(dp, name, 0)) != 0){
 | 
			
		||||
    iput(ip);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -593,53 +584,52 @@ skipelem(char *path, char *name)
 | 
			
		|||
// If parent is set, return the inode for the parent
 | 
			
		||||
// and write the final path element to name, which
 | 
			
		||||
// should have room for DIRSIZ bytes.
 | 
			
		||||
static struct uinode*
 | 
			
		||||
static struct inode*
 | 
			
		||||
_namei(char *path, int parent, char *name)
 | 
			
		||||
{
 | 
			
		||||
  struct uinode *dpu, *ipu;
 | 
			
		||||
  struct inode *dp;
 | 
			
		||||
  struct inode *ip, *next;
 | 
			
		||||
  uint off;
 | 
			
		||||
 | 
			
		||||
  if(*path == '/')
 | 
			
		||||
    dpu = iget(ROOTDEV, 1);
 | 
			
		||||
    ip = iget(ROOTDEV, 1);
 | 
			
		||||
  else
 | 
			
		||||
    dpu = idup(cp->cwd);
 | 
			
		||||
    ip = idup(cp->cwd);
 | 
			
		||||
 | 
			
		||||
  while((path = skipelem(path, name)) != 0){
 | 
			
		||||
    dp = ilock(dpu);
 | 
			
		||||
    if(dp->type != T_DIR){
 | 
			
		||||
      iput(iunlock(dp));
 | 
			
		||||
    ilock(ip);
 | 
			
		||||
    if(ip->type != T_DIR){
 | 
			
		||||
      iunlockput(ip);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(parent && *path == '\0'){
 | 
			
		||||
      // Stop one level early.
 | 
			
		||||
      iunlock(dp);
 | 
			
		||||
      return dpu;
 | 
			
		||||
      iunlock(ip);
 | 
			
		||||
      return ip;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if((ipu = dirlookup(dp, name, &off)) == 0){
 | 
			
		||||
      iput(iunlock(dp));
 | 
			
		||||
    if((next = dirlookup(ip, name, &off)) == 0){
 | 
			
		||||
      iunlockput(ip);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
    dpu = ipu;
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    ip = next;
 | 
			
		||||
  }
 | 
			
		||||
  if(parent){
 | 
			
		||||
    iput(dpu);
 | 
			
		||||
    iput(ip);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return dpu;
 | 
			
		||||
  return ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct uinode*
 | 
			
		||||
struct inode*
 | 
			
		||||
namei(char *path)
 | 
			
		||||
{
 | 
			
		||||
  char name[DIRSIZ];
 | 
			
		||||
  return _namei(path, 0, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct uinode*
 | 
			
		||||
struct inode*
 | 
			
		||||
nameiparent(char *path, char *name)
 | 
			
		||||
{
 | 
			
		||||
  return _namei(path, 1, name);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								fsvar.h
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								fsvar.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -14,11 +14,5 @@ struct inode {
 | 
			
		|||
  uint addrs[NADDRS];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// unlocked inode - only dev and inum are available
 | 
			
		||||
struct uinode {
 | 
			
		||||
  uint dev;
 | 
			
		||||
  uint inum;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define I_BUSY 0x1
 | 
			
		||||
#define I_VALID 0x2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								init.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								init.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -14,7 +14,7 @@ main(void)
 | 
			
		|||
  int pid, wpid;
 | 
			
		||||
 | 
			
		||||
  if(open("console", O_RDWR) < 0){
 | 
			
		||||
    mknod("console", T_DEV, 1, 1);
 | 
			
		||||
    mknod("console", 1, 1);
 | 
			
		||||
    open("console", O_RDWR);
 | 
			
		||||
  }
 | 
			
		||||
  dup(0);  // stdout
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								proc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -37,7 +37,7 @@ struct proc {
 | 
			
		|||
  void *chan;               // If non-zero, sleeping on chan
 | 
			
		||||
  int killed;               // If non-zero, have been killed
 | 
			
		||||
  struct file *ofile[NOFILE];  // Open files
 | 
			
		||||
  struct uinode *cwd;       // Current directory
 | 
			
		||||
  struct inode *cwd;        // Current directory
 | 
			
		||||
  struct jmpbuf jmpbuf;     // Jump here to run process
 | 
			
		||||
  struct trapframe *tf;     // Trap frame for current interrupt
 | 
			
		||||
  char name[16];            // Process name (debugging)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										111
									
								
								sysfile.c
									
										
									
									
									
								
							
							
						
						
									
										111
									
								
								sysfile.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -103,33 +103,37 @@ sys_link(void)
 | 
			
		|||
{
 | 
			
		||||
  char name[DIRSIZ], *new, *old;
 | 
			
		||||
  struct inode *dp, *ip;
 | 
			
		||||
  struct uinode *ipu;
 | 
			
		||||
 | 
			
		||||
  if(argstr(0, &old) < 0 || argstr(1, &new) < 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if((ip = ilock(namei(old))) == 0)
 | 
			
		||||
  if((ip = namei(old)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
  if(ip->type == T_DIR){
 | 
			
		||||
    iput(iunlock(ip));
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  ip->nlink++;
 | 
			
		||||
  iupdate(ip);
 | 
			
		||||
  ipu = iunlock(ip);  ip = 0;
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
 | 
			
		||||
  if((dp = ilock(nameiparent(new, name))) == 0 ||
 | 
			
		||||
     dp->dev != ipu->dev || dirlink(dp, name, ipu->inum) < 0){
 | 
			
		||||
    if(dp)
 | 
			
		||||
      iput(iunlock(dp));
 | 
			
		||||
    ip = ilock(ipu);
 | 
			
		||||
    ip->nlink--;
 | 
			
		||||
    iupdate(ip);
 | 
			
		||||
    iput(iunlock(ip));
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  iput(iunlock(dp));
 | 
			
		||||
  iput(ipu);
 | 
			
		||||
  if((dp = nameiparent(new, name)) == 0)
 | 
			
		||||
    goto  bad;
 | 
			
		||||
  ilock(dp);
 | 
			
		||||
  if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0)
 | 
			
		||||
    goto bad;
 | 
			
		||||
  iunlockput(dp);
 | 
			
		||||
  iput(ip);
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
bad:
 | 
			
		||||
  if(dp)
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
  ip->nlink--;
 | 
			
		||||
  iupdate(ip);
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Is the directory dp empty except for "." and ".." ?
 | 
			
		||||
| 
						 | 
				
			
			@ -158,65 +162,67 @@ sys_unlink(void)
 | 
			
		|||
 | 
			
		||||
  if(argstr(0, &path) < 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if((dp = ilock(nameiparent(path, name))) == 0)
 | 
			
		||||
  if((dp = nameiparent(path, name)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  ilock(dp);
 | 
			
		||||
 | 
			
		||||
  // Cannot unlink "." or "..".
 | 
			
		||||
  if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0){
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if((ip = ilock(dirlookup(dp, name, &off))) == 0){
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
  if((ip = dirlookup(dp, name, &off)) == 0){
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
 | 
			
		||||
  if(ip->nlink < 1)
 | 
			
		||||
    panic("unlink: nlink < 1");
 | 
			
		||||
  if(ip->type == T_DIR && !isdirempty(ip)){
 | 
			
		||||
    iput(iunlock(ip));
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  memset(&de, 0, sizeof(de));
 | 
			
		||||
  if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
 | 
			
		||||
    panic("unlink: writei");
 | 
			
		||||
  iput(iunlock(dp));
 | 
			
		||||
  
 | 
			
		||||
  iunlockput(dp);
 | 
			
		||||
 | 
			
		||||
  ip->nlink--;
 | 
			
		||||
  iupdate(ip);
 | 
			
		||||
  iput(iunlock(ip));
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the path and return its unlocked inode structure.
 | 
			
		||||
static struct inode*
 | 
			
		||||
mkpath(char *path, int canexist, short type, short major, short minor)
 | 
			
		||||
{
 | 
			
		||||
  uint off;
 | 
			
		||||
  struct inode *ip, *dp;
 | 
			
		||||
  struct uinode *ipu;
 | 
			
		||||
  char name[DIRSIZ];
 | 
			
		||||
 | 
			
		||||
  if((dp = ilock(nameiparent(path, name))) == 0)
 | 
			
		||||
  if((dp = nameiparent(path, name)) == 0)
 | 
			
		||||
    return 0;
 | 
			
		||||
  ilock(dp);
 | 
			
		||||
 | 
			
		||||
  if(canexist && (ipu = dirlookup(dp, name, &off)) != 0){
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
    ip = ilock(ipu);
 | 
			
		||||
  if(canexist && (ip = dirlookup(dp, name, &off)) != 0){
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    ilock(ip);
 | 
			
		||||
    if(ip->type != type || ip->major != major || ip->minor != minor){
 | 
			
		||||
      iput(iunlock(ip));
 | 
			
		||||
      iunlockput(ip);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    return ip;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if((ip = ilock(ialloc(dp->dev, type))) == 0){
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
  if((ip = ialloc(dp->dev, type)) == 0){
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
  ip->major = major;
 | 
			
		||||
  ip->minor = minor;
 | 
			
		||||
  ip->size = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -225,8 +231,8 @@ mkpath(char *path, int canexist, short type, short major, short minor)
 | 
			
		|||
  
 | 
			
		||||
  if(dirlink(dp, name, ip->inum) < 0){
 | 
			
		||||
    ip->nlink = 0;
 | 
			
		||||
    iput(iunlock(ip));
 | 
			
		||||
    iput(iunlock(dp));
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    iunlockput(dp);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +243,7 @@ mkpath(char *path, int canexist, short type, short major, short minor)
 | 
			
		|||
    if(dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0)
 | 
			
		||||
      panic("mkpath dots");
 | 
			
		||||
  }
 | 
			
		||||
  iput(iunlock(dp));
 | 
			
		||||
  iunlockput(dp);
 | 
			
		||||
  return ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -256,10 +262,11 @@ sys_open(void)
 | 
			
		|||
    if((ip = mkpath(path, 1, T_FILE, 0, 0)) == 0)
 | 
			
		||||
      return -1;
 | 
			
		||||
  }else{
 | 
			
		||||
    if((ip = ilock(namei(path))) == 0)
 | 
			
		||||
    if((ip = namei(path)) == 0)
 | 
			
		||||
      return -1;
 | 
			
		||||
    ilock(ip);
 | 
			
		||||
    if(ip->type == T_DIR && (omode & (O_RDWR|O_WRONLY))){
 | 
			
		||||
      iput(iunlock(ip));
 | 
			
		||||
      iunlockput(ip);
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -267,12 +274,13 @@ sys_open(void)
 | 
			
		|||
  if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
 | 
			
		||||
    if(f)
 | 
			
		||||
      fileclose(f);
 | 
			
		||||
    iput(iunlock(ip));
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
 | 
			
		||||
  f->type = FD_INODE;
 | 
			
		||||
  f->ip = iunlock(ip);
 | 
			
		||||
  f->ip = ip;
 | 
			
		||||
  f->off = 0;
 | 
			
		||||
  if(omode & O_RDWR) {
 | 
			
		||||
    f->readable = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -296,13 +304,12 @@ sys_mknod(void)
 | 
			
		|||
  int len;
 | 
			
		||||
  int type, major, minor;
 | 
			
		||||
  
 | 
			
		||||
  if((len=argstr(0, &path)) < 0 || argint(1, &type) < 0 ||
 | 
			
		||||
     argint(2, &major) < 0 || argint(3, &minor) < 0)
 | 
			
		||||
  if((len=argstr(0, &path)) < 0 ||
 | 
			
		||||
     argint(1, &major) < 0 ||
 | 
			
		||||
     argint(2, &minor) < 0 ||
 | 
			
		||||
     (ip = mkpath(path, 0, T_DEV, major, minor)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  // XXX check that type == T_DEV or eliminate type arg?
 | 
			
		||||
  if((ip = mkpath(path, 0, type, major, minor)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  iput(iunlock(ip));
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -314,7 +321,7 @@ sys_mkdir(void)
 | 
			
		|||
 | 
			
		||||
  if(argstr(0, &path) < 0 || (ip = mkpath(path, 0, T_DIR, 0, 0)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  iput(iunlock(ip));
 | 
			
		||||
  iunlockput(ip);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -324,14 +331,16 @@ sys_chdir(void)
 | 
			
		|||
  char *path;
 | 
			
		||||
  struct inode *ip;
 | 
			
		||||
 | 
			
		||||
  if(argstr(0, &path) < 0 || (ip = ilock(namei(path))) == 0)
 | 
			
		||||
  if(argstr(0, &path) < 0 || (ip = namei(path)) == 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
  ilock(ip);
 | 
			
		||||
  if(ip->type != T_DIR) {
 | 
			
		||||
    iput(iunlock(ip));
 | 
			
		||||
    iunlockput(ip);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  iunlock(ip);
 | 
			
		||||
  iput(cp->cwd);
 | 
			
		||||
  cp->cwd = iunlock(ip);
 | 
			
		||||
  cp->cwd = ip;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								user.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								user.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,7 @@ int close(int);
 | 
			
		|||
int kill(int);
 | 
			
		||||
int exec(char*, char**);
 | 
			
		||||
int open(char*, int);
 | 
			
		||||
int mknod(char*, short, short, short);
 | 
			
		||||
int mknod(char*, short, short);
 | 
			
		||||
int unlink(char*);
 | 
			
		||||
int fstat(int fd, struct stat*);
 | 
			
		||||
int link(char*, char*);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue