diff --git a/defs.h b/defs.h
index ba70cbb108a5f50f4169b7f5d9f01fb801280e86..cbe0dd4ba876aa6399db39877a61bb2cdf704401 100644
--- a/defs.h
+++ b/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);
diff --git a/exec.c b/exec.c
index de1175c1b89898cef4c010fd85b326811968e47b..4da73b26767971ac42c1040e895ef201b5a194fd 100644
--- a/exec.c
+++ b/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;
 }
diff --git a/file.c b/file.c
index 981d4748548030a5d275ba3fafa850c3c5b557bc..297fd1c46dec2b0964323f338c51fd4b72e7528e 100644
--- a/file.c
+++ b/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;
diff --git a/file.h b/file.h
index d8647936e3fe24d1d15aa69271938dcee4a9faf6..99f0122a6cb4f37d8925a2ae4606b847d8bd1cde 100644
--- a/file.h
+++ b/file.h
@@ -4,6 +4,6 @@ struct file {
   char readable;
   char writable;
   struct pipe *pipe;
-  struct uinode *ip;
+  struct inode *ip;
   uint off;
 };
diff --git a/fs.c b/fs.c
index 58893b1eae64fb9c50f84dab7d7c62804c850dff..bc3cccd57fc6b8a0cd4d1bd034417992063b7ca1 100644
--- a/fs.c
+++ b/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);
diff --git a/fsvar.h b/fsvar.h
index 07dbf5393803ee62a1c80d16f482a2216a0b1582..17bcb5b0055c56eb323152ed0fcd620cd1f3634e 100644
--- a/fsvar.h
+++ b/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
diff --git a/init.c b/init.c
index f8ad7b6f5f987082e4512d61c46f0e342b134043..e873f3b071c0d9b8ff5eac0f179c0d6a67fef8ff 100644
--- a/init.c
+++ b/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
diff --git a/proc.h b/proc.h
index 599ed4478187dff856785b48a613995b818482a0..84dc57d09f18e20b0f2ca01b9e726d61c688c7a1 100644
--- a/proc.h
+++ b/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)
diff --git a/sysfile.c b/sysfile.c
index 625d466d8fe3d3f07d89dbaec560c0d0125344a3..afef30488c34437ee235c8ec14e9396f366c22fb 100644
--- a/sysfile.c
+++ b/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;
-
-  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;
 }
 
diff --git a/user.h b/user.h
index bd6f72990512c3ef231482d3df2a8b7fe3e4fdd1..1bbe2fd6c0cd1d9e57da8a57d11e0d2cf19be915 100644
--- a/user.h
+++ b/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*);