diff options
| -rw-r--r-- | defs.h | 18 | ||||
| -rw-r--r-- | exec.c | 10 | ||||
| -rw-r--r-- | file.c | 22 | ||||
| -rw-r--r-- | file.h | 2 | ||||
| -rw-r--r-- | fs.c | 94 | ||||
| -rw-r--r-- | fsvar.h | 6 | ||||
| -rw-r--r-- | init.c | 2 | ||||
| -rw-r--r-- | proc.h | 2 | ||||
| -rw-r--r-- | sysfile.c | 113 | ||||
| -rw-r--r-- | user.h | 2 | 
10 files changed, 130 insertions, 141 deletions
| @@ -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); @@ -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;  } @@ -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; @@ -4,6 +4,6 @@ struct file {    char readable;    char writable;    struct pipe *pipe; -  struct uinode *ip; +  struct inode *ip;    uint off;  }; @@ -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); @@ -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 @@ -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 @@ -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) @@ -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; - -  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); +  iunlock(ip); + +  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) -    return -1; -  // XXX check that type == T_DEV or eliminate type arg? -  if((ip = mkpath(path, 0, type, major, 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; -  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;  } @@ -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*); | 
