its many limitations. @strong{You should not modify the file system
code for this project}. Proper use of the file system routines now
will make life much easier for project 4, when you improve the file
-system implementation.
+system implementation. Until then, you will have to put up with the
+following limitations:
+
+@itemize @bullet
+@item
+No synchronization. Concurrent accesses will interfere with one
+another, so external synchronization is needed. @xref{Synchronizing
+File Access}, for more details.
+
+@item
+File size is fixed at creation time. Because the root directory is
+represented as a file, the number of files that may be created is also
+limited.
+
+@item
+File data is allocated as a single extent, that is, data in a single
+file must occupy a contiguous range of sectors on disk. External
+fragmentation can therefore become a serious problem as a file system is
+used over time.
+
+@item
+No subdirectories.
+
+@item
+File names are limited to 14 characters.
+
+@item
+A system crash mid-operation may corrupt the disk in a way
+that cannot be repaired automatically. No `fsck' tool is
+provided in any case.
+@end itemize
+
+However one important feature is included:
+
+@itemize @bullet
+@item
+Unix-like semantics for filesys_remove() are implemented.
+That is, if a file is open when it is removed, its blocks
+are not deallocated and it may still be accessed by the
+threads that have it open until the last one closes it. @xref{Removing
+an Open File}, for more information.
+@end itemize
You need to be able to create and format simulated disks. The
@command{pintos} program provides this functionality with its
@itemize @bullet
@item
-The kernel should print out the program's name and exit status
-whenever a process terminates, e.g.@: @code{shell: exit(-1)}, whether
-termination is due to a call to the @code{exit} system call or for
-another reason. The name printed should be the full name passed to
+The kernel should print out the program's name and exit status whenever
+a process terminates, whether termination is caused by the @code{exit}
+system call or for another reason.
+
+@itemize @minus
+@item
+The message must be formatted exactly as if it was printed with
+@code{printf ("%s: exit(%d)\n", @dots{});} given appropriate arguments.
+
+@item
+The name printed should be the full name passed to
@func{process_execute}, except that it is acceptable to truncate it to
-15 characters to allow for the limited space in @struct{thread}.
+15 characters to allow for the limited space in @struct{thread}. The
+name printed need not include arguments.
+
+@item
+Do not print a message when a kernel thread that is not a process
+terminates.
+
+@item
+Do not print messages about process termination for the @code{halt}
+system call.
+
+@item
+No message need be printed when a process fails to load.
+@end itemize
@item
Aside from this, the kernel should print out no other messages that
@itemx pid_t exec (const char *@var{cmd_line})
Runs the executable whose name is given in @var{cmd_line}, passing any
given arguments, and returns the new process's program id (pid). If
-there is an error loading this program, returns pid -1, which
+there is an error loading this program, may return pid -1, which
otherwise should not be a valid id number.
@item SYS_join
writing and testing this code before implementing any other system
call functionality.
+@anchor{Synchronizing File Access}
You must make sure that system calls are properly synchronized so that
any number of user processes can make them at once. In particular, it
is not safe to call into the filesystem code provided in the
that @func{process_execute} also accesses files. @strong{For now, we
recommend against modifying code in the @file{filesys} directory.}
-We have provided you a function for each system call in
+We have provided you a user-level function for each system call in
@file{lib/user/syscall.c}. These provide a way for user processes to
invoke each system call from a C program. Each of them calls an
assembly language routine in @file{lib/user/syscall-stub.S}, which in
When you're done with this part, and forevermore, Pintos should be
bulletproof. Nothing that a user program can do should ever cause the
-OS to crash, halt, assert fail, or otherwise stop running. The sole
-exception is a call to the @code{halt} system call.
+OS to crash, halt, assert fail, or otherwise stop running. It is
+important to emphasize this point: our tests will try to break your
+system calls in many, many ways. You need to think of all the corner
+cases and handle them. The sole way a user program should be able to
+cause the OS to halt is by invoking the @code{halt} system call.
If a system call is passed an invalid argument, acceptable options
include returning an error value (for those calls that return a
The disk hasn't yet been formatted (with @samp{pintos run -f}).
@item
-The filename specified is too long. The file system limits file names
+The file name specified is too long. The file system limits file names
to 14 characters. If you're using a command like @samp{pintos put
../../tests/userprog/echo}, that overflows the limit. Use
@samp{pintos put ../../tests/userprog/echo echo} to put the file under
the name @file{echo} instead.
@item
-The file is too big. The file system has a 63 kB limit.
+The file system is full.
+
+@item
+The file system already contains 10 files. (There's a 10-file limit for
+the base Pintos file system.)
+
+@item
+The file system is so fragmented that there's not enough contiguous
+space for your file.
@end itemize
@item
@samp{system call!}.}
Every reasonable program tries to make at least one system call
-(@func{exit}) and most programs make more than that. The default
+(@func{exit}) and most programs make more than that. Notably,
+@func{printf} invokes the @code{write} system call. The default
system call handler just prints @samp{system call!} and terminates the
program. You'll have to implement 2-2 before you see anything more
interesting. Until then, you can use @func{hex_dump} to convince
pointer so that it is word-aligned: that is, we move it down to the
next 4-byte boundary. This is required because we will next be
placing several words of data on the stack, and they must be aligned
-in order to be read correctly. In our example, as you'll see below,
+to be read correctly. In our example, as you'll see below,
the strings start at address @t{0xffed}. One word below that would be
at @t{0xffe9}, so we could in theory put the next word on the stack
there. However, since the stack pointer should always be
The 80@var{x}86 convention for function return values is to place them
in the @samp{EAX} register. System calls that return a value can do
so by modifying the @samp{eax} member of @struct{intr_frame}.
+
+You should try to avoid writing large amounts of repetitive code for
+implementing system calls. Each system call argument, whether an
+integer or a pointer, takes up 4 bytes on the stack. You should be able
+to take advantage of this to avoid writing much near-identical code for
+retrieving each system call's arguments from the stack.