Implement a proper block layer with partition support.
[pintos-anon] / solutions / p3.patch
index 69393dfdb28f1459ed8f43564df9277db067b4dc..d3a5ddee4b8075905b2c477bebb86a649dce6986 100644 (file)
@@ -1,12 +1,12 @@
 Index: src/Makefile.build
 diff -u src/Makefile.build~ src/Makefile.build
---- src/Makefile.build~ 2005-06-18 20:20:47.000000000 -0700
-+++ src/Makefile.build 2006-04-08 18:52:50.000000000 -0700
+--- src/Makefile.build~
++++ src/Makefile.build
 @@ -53,7 +53,9 @@ userprog_SRC += userprog/gdt.c               # GDT in
  userprog_SRC += userprog/tss.c                # TSS management.
  
  # No virtual memory code yet.
--#vm_SRC = vm/filename.c                       # Some file.
+-#vm_SRC = vm/file.c                   # Some file.
 +vm_SRC = vm/page.c
 +vm_SRC += vm/frame.c
 +vm_SRC += vm/swap.c
@@ -15,8 +15,8 @@ diff -u src/Makefile.build~ src/Makefile.build
  filesys_SRC  = filesys/filesys.c      # Filesystem core.
 Index: src/devices/timer.c
 diff -u src/devices/timer.c~ src/devices/timer.c
---- src/devices/timer.c~ 2005-07-06 13:45:36.000000000 -0700
-+++ src/devices/timer.c 2006-04-08 18:52:50.000000000 -0700
+--- src/devices/timer.c~
++++ src/devices/timer.c
 @@ -23,6 +23,9 @@ static volatile int64_t ticks;
     Initialized by timer_calibrate(). */
  static unsigned loops_per_tick;
@@ -36,7 +36,7 @@ diff -u src/devices/timer.c~ src/devices/timer.c
  }
  
  /* Calibrates loops_per_tick, used to implement brief delays. */
-@@ -87,15 +92,36 @@ timer_elapsed (int64_t then) 
+@@ -93,16 +93,37 @@
    return timer_ticks () - then;
  }
  
@@ -52,7 +52,8 @@ diff -u src/devices/timer.c~ src/devices/timer.c
 +  return a->wakeup_time < b->wakeup_time;
 +}
 +
- /* Suspends execution for approximately TICKS timer ticks. */
+ /* Sleeps for approximately TICKS timer ticks.  Interrupts must
+    be turned on. */
  void
  timer_sleep (int64_t ticks) 
  {
@@ -75,7 +76,7 @@ diff -u src/devices/timer.c~ src/devices/timer.c
 +  sema_down (&t->timer_sema);
  }
  
- /* Suspends execution for approximately MS milliseconds. */
+ /* Sleeps for approximately MS milliseconds.  Interrupts must be
 @@ -132,6 +158,16 @@ timer_interrupt (struct intr_frame *args
  {
    ticks++;
@@ -95,8 +96,8 @@ diff -u src/devices/timer.c~ src/devices/timer.c
  /* Returns true if LOOPS iterations waits for more than one timer
 Index: src/threads/init.c
 diff -u src/threads/init.c~ src/threads/init.c
---- src/threads/init.c~ 2006-01-29 13:32:55.000000000 -0800
-+++ src/threads/init.c 2006-04-08 18:52:50.000000000 -0700
+--- src/threads/init.c~
++++ src/threads/init.c
 @@ -33,6 +33,8 @@
  #include "filesys/filesys.h"
  #include "filesys/fsutil.h"
@@ -105,7 +106,7 @@ diff -u src/threads/init.c~ src/threads/init.c
 +#include "vm/swap.h"
  
  /* Amount of physical memory, in 4 kB pages. */
- size_t ram_pages;
+ size_t init_ram_pages;
 @@ -124,6 +126,9 @@ main (void)
    filesys_init (format_filesys);
  #endif
@@ -118,8 +119,8 @@ diff -u src/threads/init.c~ src/threads/init.c
    /* Run actions specified on kernel command line. */
 Index: src/threads/interrupt.c
 diff -u src/threads/interrupt.c~ src/threads/interrupt.c
---- src/threads/interrupt.c~ 2006-01-29 13:32:55.000000000 -0800
-+++ src/threads/interrupt.c 2006-04-08 18:52:50.000000000 -0700
+--- src/threads/interrupt.c~
++++ src/threads/interrupt.c
 @@ -354,6 +354,8 @@ intr_handler (struct intr_frame *frame) 
        in_external_intr = true;
        yield_on_return = false;
@@ -131,10 +132,10 @@ diff -u src/threads/interrupt.c~ src/threads/interrupt.c
       If there is no handler, invoke the unexpected interrupt
 Index: src/threads/thread.c
 diff -u src/threads/thread.c~ src/threads/thread.c
---- src/threads/thread.c~ 2006-04-08 12:09:39.000000000 -0700
-+++ src/threads/thread.c 2006-04-08 18:52:50.000000000 -0700
+--- src/threads/thread.c~
++++ src/threads/thread.c
 @@ -13,6 +13,7 @@
- #include "threads/synch.h"
+ #include "threads/vaddr.h"
  #ifdef USERPROG
  #include "userprog/process.h"
 +#include "userprog/syscall.h"
@@ -173,28 +174,18 @@ diff -u src/threads/thread.c~ src/threads/thread.c
  
    /* Stack frame for kernel_thread(). */
    kf = alloc_frame (t, sizeof *kf);
-@@ -253,16 +254,19 @@ thread_tid (void) 
+@@ -288,10 +289,11 @@ thread_tid (void) 
  void
  thread_exit (void) 
  {
-+  struct thread *t = thread_current ();
-+
    ASSERT (!intr_context ());
  
 +  syscall_exit ();
  #ifdef USERPROG
    process_exit ();
  #endif
--
-+  
-   /* Just set our status to dying and schedule another process.
-      We will be destroyed during the call to schedule_tail(). */
-   intr_disable ();
--  thread_current ()->status = THREAD_DYING;
-+  t->status = THREAD_DYING;
-   schedule ();
-   NOT_REACHED ();
- }
+   /* Remove thread from all threads list, set our status to dying,
 @@ -406,17 +410,28 @@ is_thread (struct thread *t)
  /* Does basic initialization of T as a blocked thread named
     NAME. */
@@ -227,8 +218,8 @@ diff -u src/threads/thread.c~ src/threads/thread.c
  
 Index: src/threads/thread.h
 diff -u src/threads/thread.h~ src/threads/thread.h
---- src/threads/thread.h~ 2005-06-18 20:21:21.000000000 -0700
-+++ src/threads/thread.h 2006-04-08 18:52:50.000000000 -0700
+--- src/threads/thread.h~
++++ src/threads/thread.h
 @@ -2,8 +2,10 @@
  #define THREADS_THREAD_H
  
@@ -289,13 +280,13 @@ diff -u src/threads/thread.h~ src/threads/thread.h
 +    struct semaphore dead;              /* 1=child alive, 0=child dead. */
 +  };
 +
- void thread_init (void);
- void thread_start (void);
+ /* If false (default), use round-robin scheduler.
+    If true, use multi-level feedback queue scheduler.
+    Controlled by kernel command-line options "-o mlfqs".
 Index: src/userprog/exception.c
 diff -u src/userprog/exception.c~ src/userprog/exception.c
---- src/userprog/exception.c~ 2006-01-29 13:32:56.000000000 -0800
-+++ src/userprog/exception.c 2006-04-08 18:52:50.000000000 -0700
+--- src/userprog/exception.c~
++++ src/userprog/exception.c
 @@ -4,6 +4,7 @@
  #include "userprog/gdt.h"
  #include "threads/interrupt.h"
@@ -324,10 +315,10 @@ diff -u src/userprog/exception.c~ src/userprog/exception.c
            not_present ? "not present" : "rights violation",
 Index: src/userprog/pagedir.c
 diff -u src/userprog/pagedir.c~ src/userprog/pagedir.c
---- src/userprog/pagedir.c~ 2006-01-29 13:32:56.000000000 -0800
-+++ src/userprog/pagedir.c 2006-04-08 18:52:50.000000000 -0700
+--- src/userprog/pagedir.c~
++++ src/userprog/pagedir.c
 @@ -35,15 +35,7 @@ pagedir_destroy (uint32_t *pd) 
-   ASSERT (pd != base_page_dir);
+   ASSERT (pd != init_page_dir);
    for (pde = pd; pde < pd + pd_no (PHYS_BASE); pde++)
      if (*pde & PTE_P) 
 -      {
@@ -345,9 +336,10 @@ diff -u src/userprog/pagedir.c~ src/userprog/pagedir.c
  
 Index: src/userprog/process.c
 diff -u src/userprog/process.c~ src/userprog/process.c
---- src/userprog/process.c~ 2006-04-08 19:37:00.000000000 -0700
-+++ src/userprog/process.c 2006-04-08 19:35:29.000000000 -0700
-@@ -15,11 +15,25 @@
+--- src/userprog/process.c~
++++ src/userprog/process.c
+@@ -14,12 +14,26 @@
+ #include "threads/flags.h"
  #include "threads/init.h"
  #include "threads/interrupt.h"
 +#include "threads/malloc.h"
@@ -357,26 +349,26 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +#include "vm/page.h"
 +#include "vm/frame.h"
  
- static thread_func execute_thread NO_RETURN;
+ static thread_func start_process NO_RETURN;
 -static bool load (const char *cmdline, void (**eip) (void), void **esp);
 +static bool load (const char *cmd_line, void (**eip) (void), void **esp);
 +
 +/* Data structure shared between process_execute() in the
-+   invoking thread and execute_thread() in the newly invoked
++   invoking thread and start_process() in the newly invoked
 +   thread. */
 +struct exec_info 
 +  {
-+    const char *filename;               /* Program to load. */
++    const char *file_name;              /* Program to load. */
 +    struct semaphore load_done;         /* "Up"ed when loading complete. */
 +    struct wait_status *wait_status;    /* Child process. */
 +    bool success;                       /* Program successfully loaded? */
 +  };
  
  /* Starts a new thread running a user program loaded from
-    FILENAME.  The new thread may be scheduled (and may even exit)
+    FILE_NAME.  The new thread may be scheduled (and may even exit)
 @@ -28,29 +42,37 @@ static bool load (const char *cmdline, v
  tid_t
- process_execute (const char *filename) 
+ process_execute (const char *file_name) 
  {
 -  char *fn_copy;
 +  struct exec_info exec;
@@ -384,23 +376,23 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +  char *save_ptr;
    tid_t tid;
  
--  /* Make a copy of FILENAME.
+-  /* Make a copy of FILE_NAME.
 -     Otherwise there's a race between the caller and load(). */
 -  fn_copy = palloc_get_page (0);
 -  if (fn_copy == NULL)
 -    return TID_ERROR;
--  strlcpy (fn_copy, filename, PGSIZE);
+-  strlcpy (fn_copy, file_name, PGSIZE);
 +  /* Initialize exec_info. */
-+  exec.filename = filename;
++  exec.file_name = file_name;
 +  sema_init (&exec.load_done, 0);
  
-   /* Create a new thread to execute FILENAME. */
--  tid = thread_create (filename, PRI_DEFAULT, execute_thread, fn_copy);
+   /* Create a new thread to execute FILE_NAME. */
+-  tid = thread_create (file_name, PRI_DEFAULT, start_process, fn_copy);
 -  if (tid == TID_ERROR)
 -    palloc_free_page (fn_copy); 
-+  strlcpy (thread_name, filename, sizeof thread_name);
++  strlcpy (thread_name, file_name, sizeof thread_name);
 +  strtok_r (thread_name, " ", &save_ptr);
-+  tid = thread_create (thread_name, PRI_DEFAULT, execute_thread, &exec);
++  tid = thread_create (thread_name, PRI_DEFAULT, start_process, &exec);
 +  if (tid != TID_ERROR)
 +    {
 +      sema_down (&exec.load_done);
@@ -416,20 +408,20 @@ diff -u src/userprog/process.c~ src/userprog/process.c
  /* A thread function that loads a user process and starts it
     running. */
  static void
--execute_thread (void *filename_)
-+execute_thread (void *exec_)
+-start_process (void *file_name_)
++start_process (void *exec_)
  {
--  char *filename = filename_;
+-  char *file_name = file_name_;
 +  struct exec_info *exec = exec_;
    struct intr_frame if_;
    bool success;
  
-@@ -59,10 +81,28 @@ execute_thread (void *filename_)
+@@ -59,10 +81,28 @@ start_process (void *file_name_)
    if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
    if_.cs = SEL_UCSEG;
    if_.eflags = FLAG_IF | FLAG_MBS;
--  success = load (filename, &if_.eip, &if_.esp);
-+  success = load (exec->filename, &if_.eip, &if_.esp);
+-  success = load (file_name, &if_.eip, &if_.esp);
++  success = load (exec->file_name, &if_.eip, &if_.esp);
 +
 +  /* Allocate wait_status. */
 +  if (success)
@@ -440,7 +432,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +    }
  
 -  /* If load failed, quit. */
--  palloc_free_page (filename);
+-  palloc_free_page (file_name);
 +  /* Initialize wait_status. */
 +  if (success) 
 +    {
@@ -456,7 +448,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
    if (!success) 
      thread_exit ();
  
-@@ -76,18 +116,47 @@ execute_thread (void *filename_)
+@@ -76,18 +116,47 @@ start_process (void *file_name_)
    NOT_REACHED ();
  }
  
@@ -558,11 +550,11 @@ diff -u src/userprog/process.c~ src/userprog/process.c
     and its initial stack pointer into *ESP.
     Returns true if successful, false otherwise. */
  bool
--load (const char *filename, void (**eip) (void), void **esp) 
+-load (const char *file_name, void (**eip) (void), void **esp) 
 +load (const char *cmd_line, void (**eip) (void), void **esp) 
  {
    struct thread *t = thread_current ();
-+  char filename[NAME_MAX + 2];
++  char file_name[NAME_MAX + 2];
    struct Elf32_Ehdr ehdr;
    struct file *file = NULL;
    off_t file_ofs;
@@ -571,7 +563,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
    int i;
  
    /* Allocate and activate page directory. */
-@@ -220,13 +318,28 @@ load (const char *filename, void (**eip)
+@@ -220,13 +318,28 @@ load (const char *file_name, void (**eip)
      goto done;
    process_activate ();
  
@@ -581,27 +573,27 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +    goto done;
 +  hash_init (t->pages, page_hash, page_less, NULL);
 +
-+  /* Extract filename from command line. */
++  /* Extract file_name from command line. */
 +  while (*cmd_line == ' ')
 +    cmd_line++;
-+  strlcpy (filename, cmd_line, sizeof filename);
-+  cp = strchr (filename, ' ');
++  strlcpy (file_name, cmd_line, sizeof file_name);
++  cp = strchr (file_name, ' ');
 +  if (cp != NULL)
 +    *cp = '\0';
 +
    /* Open executable file. */
--  file = filesys_open (filename);
-+  t->bin_file = file = filesys_open (filename);
+-  file = filesys_open (file_name);
++  t->bin_file = file = filesys_open (file_name);
    if (file == NULL) 
      {
-       printf ("load: %s: open failed\n", filename);
+       printf ("load: %s: open failed\n", file_name);
        goto done; 
      }
 +  file_deny_write (t->bin_file);
  
    /* Read and verify executable header. */
    if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr
-@@ -301,7 +414,7 @@ load (const char *filename, void (**eip)
+@@ -301,7 +414,7 @@ load (const char *file_name, void (**eip)
      }
  
    /* Set up stack. */
@@ -610,7 +602,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
      goto done;
  
    /* Start address. */
-@@ -311,14 +424,11 @@ load (const char *filename, void (**eip)
+@@ -311,14 +424,11 @@ load (const char *file_name, void (**eip)
  
   done:
    /* We arrive here whether the load is successful or not. */
@@ -807,26 +799,26 @@ diff -u src/userprog/process.c~ src/userprog/process.c
  }
 Index: src/userprog/syscall.c
 diff -u src/userprog/syscall.c~ src/userprog/syscall.c
---- src/userprog/syscall.c~ 2005-06-18 20:21:21.000000000 -0700
-+++ src/userprog/syscall.c 2006-04-08 19:36:04.000000000 -0700
-@@ -1,20 +1,557 @@
+--- src/userprog/syscall.c~
++++ src/userprog/syscall.c
+@@ -1,20 +1,598 @@
  #include "userprog/syscall.h"
  #include <stdio.h>
 +#include <string.h>
  #include <syscall-nr.h>
 +#include "userprog/process.h"
 +#include "userprog/pagedir.h"
-+#include "devices/kbd.h"
++#include "devices/input.h"
++#include "devices/shutdown.h"
 +#include "filesys/directory.h"
 +#include "filesys/filesys.h"
 +#include "filesys/file.h"
-+#include "threads/init.h"
  #include "threads/interrupt.h"
 +#include "threads/malloc.h"
 +#include "threads/palloc.h"
  #include "threads/thread.h"
-+#include "threads/vaddr.h"
 -
++#include "threads/vaddr.h"
 +#include "vm/page.h"
 + 
 + 
@@ -847,13 +839,15 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +static int sys_munmap (int mapping);
 + 
  static void syscall_handler (struct intr_frame *);
--
 +static void copy_in (void *, const void *, size_t);
++static struct lock fs_lock;
 + 
  void
  syscall_init (void) 
  {
    intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
++  lock_init (&fs_lock);
  }
 + 
 +/* System call handler. */
@@ -888,11 +882,11 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +      {2, (syscall_function *) sys_mmap},
 +      {1, (syscall_function *) sys_munmap},
 +    };
++
 +  const struct syscall *sc;
 +  unsigned call_nr;
 +  int args[3];
-+
 +  /* Get the system call. */
 +  copy_in (&call_nr, f->esp, sizeof call_nr);
 +  if (call_nr >= sizeof syscall_table / sizeof *syscall_table)
@@ -985,7 +979,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +static int
 +sys_halt (void)
 +{
-+  power_off ();
++  shutdown_power_off ();
 +}
 + 
 +/* Exit system call. */
@@ -1003,8 +997,10 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +{
 +  tid_t tid;
 +  char *kfile = copy_in_string (ufile);
-+ 
++
++  lock_acquire (&fs_lock);
 +  tid = process_execute (kfile);
++  lock_release (&fs_lock);
 + 
 +  palloc_free_page (kfile);
 + 
@@ -1023,7 +1019,12 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +sys_create (const char *ufile, unsigned initial_size) 
 +{
 +  char *kfile = copy_in_string (ufile);
-+  bool ok = filesys_create (kfile, initial_size);
++  bool ok;
++
++  lock_acquire (&fs_lock);
++  ok = filesys_create (kfile, initial_size);
++  lock_release (&fs_lock);
++
 +  palloc_free_page (kfile);
 + 
 +  return ok;
@@ -1034,7 +1035,12 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +sys_remove (const char *ufile) 
 +{
 +  char *kfile = copy_in_string (ufile);
-+  bool ok = filesys_remove (kfile);
++  bool ok;
++
++  lock_acquire (&fs_lock);
++  ok = filesys_remove (kfile);
++  lock_release (&fs_lock);
++
 +  palloc_free_page (kfile);
 + 
 +  return ok;
@@ -1059,6 +1065,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +  fd = malloc (sizeof *fd);
 +  if (fd != NULL)
 +    {
++      lock_acquire (&fs_lock);
 +      fd->file = filesys_open (kfile);
 +      if (fd->file != NULL)
 +        {
@@ -1068,6 +1075,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +        }
 +      else 
 +        free (fd);
++      lock_release (&fs_lock);
 +    }
 +  
 +  palloc_free_page (kfile);
@@ -1102,7 +1110,9 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +  struct file_descriptor *fd = lookup_fd (handle);
 +  int size;
 + 
++  lock_acquire (&fs_lock);
 +  size = file_length (fd->file);
++  lock_release (&fs_lock);
 + 
 +  return size;
 +}
@@ -1116,10 +1126,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +  struct file_descriptor *fd;
 +  int bytes_read = 0;
 +
-+  /* Look up file descriptor. */
-+  if (handle != STDIN_FILENO)
-+    fd = lookup_fd (handle);
-+
++  fd = lookup_fd (handle);
 +  while (size > 0) 
 +    {
 +      /* How much to read into this page? */
@@ -1127,37 +1134,44 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +      size_t read_amt = size < page_left ? size : page_left;
 +      off_t retval;
 +
-+      /* Check that touching this page is okay. */
-+      if (!page_lock (udst, true)) 
-+        thread_exit ();
-+
 +      /* Read from file into page. */
 +      if (handle != STDIN_FILENO) 
 +        {
++          if (!page_lock (udst, true)) 
++            thread_exit (); 
++          lock_acquire (&fs_lock);
 +          retval = file_read (fd->file, udst, read_amt);
-+          if (retval < 0)
-+            {
-+              if (bytes_read == 0)
-+                bytes_read = -1; 
-+              break;
-+            }
-+          bytes_read += retval; 
++          lock_release (&fs_lock);
++          page_unlock (udst);
 +        }
 +      else 
 +        {
 +          size_t i;
 +          
 +          for (i = 0; i < read_amt; i++) 
-+            udst[i] = kbd_getc ();
++            {
++              char c = input_getc ();
++              if (!page_lock (udst, true)) 
++                thread_exit ();
++              udst[i] = c;
++              page_unlock (udst);
++            }
 +          bytes_read = read_amt;
 +        }
-+
-+      /* Release page. */
-+      page_unlock (udst);
-+
-+      /* If it was a short read we're done. */
-+      if (retval != (off_t) read_amt)
-+        break;
++      
++      /* Check success. */
++      if (retval < 0)
++        {
++          if (bytes_read == 0)
++            bytes_read = -1; 
++          break;
++        }
++      bytes_read += retval; 
++      if (retval != (off_t) read_amt) 
++        {
++          /* Short read, so we're done. */
++          break; 
++        }
 +
 +      /* Advance. */
 +      udst += retval;
@@ -1186,11 +1200,10 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +      size_t write_amt = size < page_left ? size : page_left;
 +      off_t retval;
 +
-+      /* Check that we can touch this user page. */
++      /* Write from page into file. */
 +      if (!page_lock (usrc, false)) 
 +        thread_exit ();
-+
-+      /* Do the write. */
++      lock_acquire (&fs_lock);
 +      if (handle == STDOUT_FILENO)
 +        {
 +          putbuf ((char *) usrc, write_amt);
@@ -1198,8 +1211,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +        }
 +      else
 +        retval = file_write (fd->file, usrc, write_amt);
-+
-+      /* Release user page. */
++      lock_release (&fs_lock);
 +      page_unlock (usrc);
 +
 +      /* Handle return value. */
@@ -1227,8 +1239,13 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +static int
 +sys_seek (int handle, unsigned position) 
 +{
++  struct file_descriptor *fd = lookup_fd (handle);
++   
++  lock_acquire (&fs_lock);
 +  if ((off_t) position >= 0)
-+    file_seek (lookup_fd (handle)->file, position);
++    file_seek (fd->file, position);
++  lock_release (&fs_lock);
++
 +  return 0;
 +}
 + 
@@ -1236,7 +1253,14 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +static int
 +sys_tell (int handle) 
 +{
-+  return file_tell (lookup_fd (handle)->file);
++  struct file_descriptor *fd = lookup_fd (handle);
++  unsigned position;
++   
++  lock_acquire (&fs_lock);
++  position = file_tell (fd->file);
++  lock_release (&fs_lock);
++
++  return position;
 +}
 + 
 +/* Close system call. */
@@ -1244,7 +1268,9 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +sys_close (int handle) 
 +{
 +  struct file_descriptor *fd = lookup_fd (handle);
++  lock_acquire (&fs_lock);
 +  file_close (fd->file);
++  lock_release (&fs_lock);
 +  list_remove (&fd->elem);
 +  free (fd);
 +  return 0;
@@ -1308,7 +1334,9 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +    return -1;
 +
 +  m->handle = thread_current ()->next_handle++;
++  lock_acquire (&fs_lock);
 +  m->file = file_reopen (fd->file);
++  lock_release (&fs_lock);
 +  if (m->file == NULL) 
 +    {
 +      free (m);
@@ -1319,7 +1347,9 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +  list_push_front (&thread_current ()->mappings, &m->elem);
 +
 +  offset = 0;
++  lock_acquire (&fs_lock);
 +  length = file_length (m->file);
++  lock_release (&fs_lock);
 +  while (length > 0)
 +    {
 +      struct page *p = page_allocate ((uint8_t *) addr + offset, false);
@@ -1359,7 +1389,9 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +    {
 +      struct file_descriptor *fd = list_entry (e, struct file_descriptor, elem);
 +      next = list_next (e);
++      lock_acquire (&fs_lock);
 +      file_close (fd->file);
++      lock_release (&fs_lock);
 +      free (fd);
 +    }
 +   
@@ -1373,8 +1405,8 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +}
 Index: src/userprog/syscall.h
 diff -u src/userprog/syscall.h~ src/userprog/syscall.h
---- src/userprog/syscall.h~ 2004-09-05 22:38:45.000000000 -0700
-+++ src/userprog/syscall.h 2006-04-08 18:52:50.000000000 -0700
+--- src/userprog/syscall.h~
++++ src/userprog/syscall.h
 @@ -2,5 +2,6 @@
  #define USERPROG_SYSCALL_H
  
@@ -1384,8 +1416,8 @@ diff -u src/userprog/syscall.h~ src/userprog/syscall.h
  #endif /* userprog/syscall.h */
 Index: src/vm/frame.c
 diff -u src/vm/frame.c~ src/vm/frame.c
---- src/vm/frame.c~ 1969-12-31 16:00:00.000000000 -0800
-+++ src/vm/frame.c 2006-04-08 18:52:50.000000000 -0700
+--- src/vm/frame.c~
++++ src/vm/frame.c
 @@ -0,0 +1,162 @@
 +#include "vm/frame.h"
 +#include <stdio.h>
@@ -1411,7 +1443,7 @@ diff -u src/vm/frame.c~ src/vm/frame.c
 +
 +  lock_init (&scan_lock);
 +  
-+  frames = malloc (sizeof *frames * ram_pages);
++  frames = malloc (sizeof *frames * init_ram_pages);
 +  if (frames == NULL)
 +    PANIC ("out of memory allocating page frames");
 +
@@ -1551,8 +1583,8 @@ diff -u src/vm/frame.c~ src/vm/frame.c
 +}
 Index: src/vm/frame.h
 diff -u src/vm/frame.h~ src/vm/frame.h
---- src/vm/frame.h~ 1969-12-31 16:00:00.000000000 -0800
-+++ src/vm/frame.h 2006-04-08 18:52:50.000000000 -0700
+--- src/vm/frame.h~
++++ src/vm/frame.h
 @@ -0,0 +1,23 @@
 +#ifndef VM_FRAME_H
 +#define VM_FRAME_H
@@ -1579,8 +1611,8 @@ diff -u src/vm/frame.h~ src/vm/frame.h
 +#endif /* vm/frame.h */
 Index: src/vm/page.c
 diff -u src/vm/page.c~ src/vm/page.c
---- src/vm/page.c~ 1969-12-31 16:00:00.000000000 -0800
-+++ src/vm/page.c 2006-04-08 18:52:50.000000000 -0700
+--- src/vm/page.c~
++++ src/vm/page.c
 @@ -0,0 +1,293 @@
 +#include "vm/page.h"
 +#include <stdio.h>
@@ -1653,7 +1685,7 @@ diff -u src/vm/page.c~ src/vm/page.c
 +    return false;
 +
 +  /* Copy data into the frame. */
-+  if (p->sector != (disk_sector_t) -1) 
++  if (p->sector != (block_sector_t) -1) 
 +    {
 +      /* Get data from swap. */
 +      swap_in (p); 
@@ -1791,7 +1823,7 @@ diff -u src/vm/page.c~ src/vm/page.c
 +
 +      p->frame = NULL;
 +
-+      p->sector = (disk_sector_t) -1;
++      p->sector = (block_sector_t) -1;
 +
 +      p->file = NULL;
 +      p->file_offset = 0;
@@ -1877,14 +1909,14 @@ diff -u src/vm/page.c~ src/vm/page.c
 +}
 Index: src/vm/page.h
 diff -u src/vm/page.h~ src/vm/page.h
---- src/vm/page.h~ 1969-12-31 16:00:00.000000000 -0800
-+++ src/vm/page.h 2006-04-08 18:52:50.000000000 -0700
+--- src/vm/page.h~
++++ src/vm/page.h
 @@ -0,0 +1,50 @@
 +#ifndef VM_PAGE_H
 +#define VM_PAGE_H
 +
 +#include <hash.h>
-+#include "devices/disk.h"
++#include "devices/block.h"
 +#include "filesys/off_t.h"
 +#include "threads/synch.h"
 +
@@ -1904,7 +1936,7 @@ diff -u src/vm/page.h~ src/vm/page.h
 +    struct frame *frame;        /* Page frame. */
 +
 +    /* Swap information, protected by frame->frame_lock. */
-+    disk_sector_t sector;       /* Starting sector of swap area, or -1. */
++    block_sector_t sector;       /* Starting sector of swap area, or -1. */
 +    
 +    /* Memory-mapped file information, protected by frame->frame_lock. */
 +    bool private;               /* False to write back to file,
@@ -1932,8 +1964,8 @@ diff -u src/vm/page.h~ src/vm/page.h
 +#endif /* vm/page.h */
 Index: src/vm/swap.c
 diff -u src/vm/swap.c~ src/vm/swap.c
---- src/vm/swap.c~ 1969-12-31 16:00:00.000000000 -0800
-+++ src/vm/swap.c 2006-04-08 18:52:50.000000000 -0700
+--- src/vm/swap.c~
++++ src/vm/swap.c
 @@ -0,0 +1,85 @@
 +#include "vm/swap.h"
 +#include <bitmap.h>
@@ -1941,12 +1973,11 @@ diff -u src/vm/swap.c~ src/vm/swap.c
 +#include <stdio.h>
 +#include "vm/frame.h"
 +#include "vm/page.h"
-+#include "devices/disk.h"
 +#include "threads/synch.h"
 +#include "threads/vaddr.h"
 +
-+/* The swap disk. */
-+static struct disk *swap_disk;
++/* The swap device. */
++static struct block *swap_device;
 +
 +/* Used swap pages. */
 +static struct bitmap *swap_bitmap;
@@ -1955,20 +1986,21 @@ diff -u src/vm/swap.c~ src/vm/swap.c
 +static struct lock swap_lock;
 +
 +/* Number of sectors per page. */
-+#define PAGE_SECTORS (PGSIZE / DISK_SECTOR_SIZE)
++#define PAGE_SECTORS (PGSIZE / BLOCK_SECTOR_SIZE)
 +
 +/* Sets up swap. */
 +void
 +swap_init (void) 
 +{
-+  swap_disk = disk_get (1, 1);
-+  if (swap_disk == NULL) 
++  swap_device = block_get_role (BLOCK_SWAP);
++  if (swap_device == NULL) 
 +    {
-+      printf ("no swap disk--swap disabled\n");
++      printf ("no swap device--swap disabled\n");
 +      swap_bitmap = bitmap_create (0);
 +    }
 +  else
-+    swap_bitmap = bitmap_create (disk_size (swap_disk) / PAGE_SECTORS);
++    swap_bitmap = bitmap_create (block_size (swap_device)
++                                 / PAGE_SECTORS);
 +  if (swap_bitmap == NULL)
 +    PANIC ("couldn't create swap bitmap");
 +  lock_init (&swap_lock);
@@ -1983,13 +2015,13 @@ diff -u src/vm/swap.c~ src/vm/swap.c
 +  
 +  ASSERT (p->frame != NULL);
 +  ASSERT (lock_held_by_current_thread (&p->frame->lock));
-+  ASSERT (p->sector != (disk_sector_t) -1);
++  ASSERT (p->sector != (block_sector_t) -1);
 +
 +  for (i = 0; i < PAGE_SECTORS; i++)
-+    disk_read (swap_disk, p->sector + i,
-+               p->frame->base + i * DISK_SECTOR_SIZE);
++    block_read (swap_device, p->sector + i,
++                p->frame->base + i * BLOCK_SECTOR_SIZE);
 +  bitmap_reset (swap_bitmap, p->sector / PAGE_SECTORS);
-+  p->sector = (disk_sector_t) -1;
++  p->sector = (block_sector_t) -1;
 +}
 +
 +/* Swaps out page P, which must have a locked frame. */
@@ -2010,8 +2042,8 @@ diff -u src/vm/swap.c~ src/vm/swap.c
 +
 +  p->sector = slot * PAGE_SECTORS;
 +  for (i = 0; i < PAGE_SECTORS; i++)
-+    disk_write (swap_disk, p->sector + i,
-+                p->frame->base + i * DISK_SECTOR_SIZE);
++    block_write (swap_device, p->sector + i,
++                 p->frame->base + i * BLOCK_SECTOR_SIZE);
 +  
 +  p->private = false;
 +  p->file = NULL;
@@ -2022,8 +2054,8 @@ diff -u src/vm/swap.c~ src/vm/swap.c
 +}
 Index: src/vm/swap.h
 diff -u src/vm/swap.h~ src/vm/swap.h
---- src/vm/swap.h~ 1969-12-31 16:00:00.000000000 -0800
-+++ src/vm/swap.h 2006-04-08 18:52:50.000000000 -0700
+--- src/vm/swap.h~
++++ src/vm/swap.h
 @@ -0,0 +1,11 @@
 +#ifndef VM_SWAP_H
 +#define VM_SWAP_H 1