diff --git a/file.c b/file.c
index cfbd7c96f67469bbb0f3b8f9e3ef1cc3509ef1ef..47e4629865ad1bd5758f9e95a5bb21694c528361 100644
--- a/file.c
+++ b/file.c
@@ -41,75 +41,55 @@ filealloc(void)
   return 0;
 }
 
-// Write to file f.  Addr is kernel address.
-int
-filewrite(struct file *f, char *addr, int n)
+// Increment ref count for file f.
+void
+fileincref(struct file *f)
 {
-  if(f->writable == 0)
-    return -1;
-  if(f->type == FD_PIPE){
-    return pipe_write(f->pipe, addr, n);
-  } else if(f->type == FD_FILE) {
-    ilock(f->ip);
-    int r = writei(f->ip, addr, f->off, n);
-    if(r > 0) {
-      f->off += r;
-    }
-    iunlock(f->ip);
-    return r;
-  } else {
-    panic("filewrite");
-    return -1;
-  }
+  acquire(&file_table_lock);
+  if(f->ref < 1 || f->type == FD_CLOSED)
+    panic("fileincref");
+  f->ref++;
+  release(&file_table_lock);
 }
 
 // Read from file f.  Addr is kernel address.
 int
 fileread(struct file *f, char *addr, int n)
 {
+  int r;
+
   if(f->readable == 0)
     return -1;
-  if(f->type == FD_PIPE){
+  if(f->type == FD_PIPE)
     return pipe_read(f->pipe, addr, n);
-  } else if(f->type == FD_FILE){
+  if(f->type == FD_FILE){
     ilock(f->ip);
-    int cc = readi(f->ip, addr, f->off, n);
-    if(cc > 0)
-      f->off += cc;
+    if((r = readi(f->ip, addr, f->off, n)) > 0)
+      f->off += r;
     iunlock(f->ip);
-    return cc;
-  } else {
-    panic("fileread");
-    return -1;
+    return r;
   }
+  panic("fileread");
 }
 
-// Close file f.  (Decrement ref count, close when reaches 0.)
-void
-fileclose(struct file *f)
+// Write to file f.  Addr is kernel address.
+int
+filewrite(struct file *f, char *addr, int n)
 {
-  acquire(&file_table_lock);
-
-  if(f->ref < 1 || f->type == FD_CLOSED)
-    panic("fileclose");
+  int r;
 
-  if(--f->ref == 0){
-    struct file dummy = *f;
-
-    f->ref = 0;
-    f->type = FD_CLOSED;
-    release(&file_table_lock);
-
-    if(dummy.type == FD_PIPE){
-      pipe_close(dummy.pipe, dummy.writable);
-    } else if(dummy.type == FD_FILE){
-      idecref(dummy.ip);
-    } else {
-      panic("fileclose");
-    }
-  } else {
-    release(&file_table_lock);
+  if(f->writable == 0)
+    return -1;
+  if(f->type == FD_PIPE)
+    return pipe_write(f->pipe, addr, n);
+  if(f->type == FD_FILE){
+    ilock(f->ip);
+    if((r = writei(f->ip, addr, f->off, n)) > 0)
+      f->off += r;
+    iunlock(f->ip);
+    return r;
   }
+  panic("filewrite");
 }
 
 // Get metadata about file f.
@@ -121,17 +101,35 @@ filestat(struct file *f, struct stat *st)
     stati(f->ip, st);
     iunlock(f->ip);
     return 0;
-  } else
-    return -1;
+  }
+  return -1;
 }
 
-// Increment ref count for file f.
+// Close file f.  (Decrement ref count, close when reaches 0.)
 void
-fileincref(struct file *f)
+fileclose(struct file *f)
 {
+  struct file ff;
   acquire(&file_table_lock);
+
   if(f->ref < 1 || f->type == FD_CLOSED)
-    panic("fileincref");
-  f->ref++;
+    panic("fileclose");
+
+  if(--f->ref > 0){
+    release(&file_table_lock);
+    return;
+  }
+  
+  ff = *f;
+  f->ref = 0;
+  f->type = FD_CLOSED;
   release(&file_table_lock);
+  
+  if(ff.type == FD_PIPE)
+    pipe_close(ff.pipe, ff.writable);
+  else if(ff.type == FD_FILE)
+    idecref(ff.ip);
+  else
+    panic("fileclose");
 }
+