Clarifications.
[pintos-anon] / doc / filesys.texi
index d580a0d7fb6fb2d43c8a829d05578dd593399425..cc00b402db7dd038e4f59fea49c2e0bb159a22b0 100644 (file)
@@ -91,7 +91,7 @@ Modify the file system to allow the maximum size of a file to be as
 large as the disk.  You can assume that the disk will not be larger
 than 8 MB.  In the basic file system, each file is limited to a file
 size of just under 64 kB.  Each file has a header called an index node
-or @dfn{inode} (represented by @code{struct inode}) that is a table of
+or @dfn{inode} (represented by @struct{inode}) that is a table of
 direct pointers to the disk blocks for that file.  Since the inode is
 stored in one disk sector, the maximum size of a file is limited by
 the number of pointers that will fit in one disk sector.  Increasing
@@ -128,8 +128,15 @@ only once).
 Make sure that directories can expand beyond their original size just
 as any other file can.
 
-To take advantage of hierarchical name spaces in user programs,
-provide the following syscalls:
+Each program has its own current directory.  When one process starts
+another with the @code{exec} system call, the child process inherits its
+parent's current directory.  After that, the two processes' current
+directories are independent, so that either changing its own current
+directory has no effect on the other.
+
+Update the existing system calls so that, anywhere a file name is
+provided by the caller, an absolute or relative path name may used.
+Also, implement the following new system calls:
 
 @table @code
 @item SYS_chdir
@@ -150,7 +157,7 @@ per line.
 @end table
 
 Also write the @command{ls} and @command{mkdir} user programs.  This
-is straightforward once the above syscalls are implemented.  If Unix,
+is straightforward once the above syscalls are implemented.  In Unix,
 these are programs rather than built-in shell commands, but
 @command{cd} is a shell command.  (Why?)
 
@@ -167,7 +174,19 @@ replacement algorithm.  Experiment to see what combination of accessed,
 dirty, and other information results in the best performance, as
 measured by the number of disk accesses.  (For example, metadata is
 generally more valuable to cache than data.)  Document your
-replacement algoritm in your design document.
+replacement algorithm in your design document.
+
+The provided file system code uses a ``bounce buffer'' in @struct{file}
+to translate the disk's sector-by-sector interface into the system call
+interface's byte-by-byte interface.  It needs per-file buffers because,
+without them, there's no other good place to put sector
+data.@footnote{The stack is not a good place because large objects
+should not be allocated on the stack.  A 512-byte sector is pushing the
+limit there.}  As part of implementing the buffer cache, you should get
+rid of these bounce buffers.  Instead, copy data into and out of sectors
+in the buffer cache directly.  You will probably need some
+synchronization to prevent sectors from being evicted from the cache
+while you are using them.
 
 In addition to the basic file caching scheme, your implementation
 should also include the following enhancements:
@@ -191,9 +210,9 @@ to perform better than on the original file system implementation, and
 demonstrate the performance improvement.
 
 Note that write-behind makes your filesystem more fragile in the face
-of crashes.  Therefore, you should implement some manner to
+of crashes.  Therefore, you should
 periodically write all cached blocks to disk.  If you have
-@code{timer_sleep()} from the first project working, this is an
+@func{timer_sleep} from the first project working, this is an
 excellent application for it.
 
 Likewise, read-ahead is only really useful when done asynchronously.
@@ -270,11 +289,10 @@ document.
 @b{What exec modes for running Pintos do I absolutely need to
 support?}
 
-You also need to support the @option{-f}, @option{-ci}, and
-@option{-ex} flags individually, and you need to handle them when
+You also need to support the @option{-f}, @option{-ci}, @option{-co},
+and @option{-ex} flags individually, and you need to handle them when
 they're combined, like this: @samp{pintos -f -ci shell 12345 -ex
-"shell"}.  Thus, you should be able to treat the above as equivalent
-to:
+"shell"}.  Thus, you should be able to treat the above as equivalent to:
 
 @example
 pintos -f
@@ -286,6 +304,9 @@ If you don't change the filesystem interface, then this should already
 be implemented properly in @file{threads/init.c} and
 @file{filesys/fsutil.c}.
 
+You must also implement the @option{-q} option and make sure that data
+gets flushed out to disk properly when it is used.
+
 @item
 @b{Will you test our file system with a different @code{DISK_SECTOR_SIZE}?}
 
@@ -293,11 +314,16 @@ No, @code{DISK_SECTOR_SIZE} is fixed at 512.  This is a fixed property
 of IDE disk hardware.
 
 @item
-@b{Will the @code{struct inode} take up space on the disk too?}
+@b{Will the @struct{inode} take up space on the disk too?}
 
-Yes.  Anything stored in @code{struct inode} takes up space on disk,
+Yes.  Anything stored in @struct{inode} takes up space on disk,
 so you must include this in your calculation of how many entires will
 fit in a single disk sector.
+
+@item
+@b{What's the directory separator character?}
+
+Forward slash (@samp{/}).
 @end enumerate
 
 @menu
@@ -315,7 +341,7 @@ fit in a single disk sector.
 
 The disk we create will be 8 MB or smaller.  However, individual files
 will have to be smaller than the disk to accommodate the metadata.
-You'll need to consider this when deciding your @code{struct inode}
+You'll need to consider this when deciding your @struct{inode}
 organization.
 @end enumerate
 
@@ -372,7 +398,7 @@ End of directory
 Yes.  Implementing @file{.} and @file{..} is extra credit, though.
 
 @item
-@b{Should @code{remove()} also be able to remove directories?}
+@b{Should @func{remove} also be able to remove directories?}
 
 Yes.  The @code{remove} system call should handle removal of both
 regular files and directories.  You may assume that directories can
@@ -384,42 +410,38 @@ only be deleted if they are empty, as in Unix.
 
 @enumerate 1
 @item
-@b{We're limited to a 64-block cache, but can we also keep a copy of
-each @code{struct inode} for an open file inside @code{struct file},
-the way the stub code does?}
-
-No, you shouldn't keep any disk sectors stored anywhere outside the
-cache.  That means you'll have to change the way the file
-implementation accesses its corresponding inode right now, since it
-currently just creates a new @code{struct inode} in its constructor
-and reads the corresponding sector in from disk when it's created.
-
-There are two reasons for not storing inodes in @code{struct file}.
+@b{We're limited to a 64-block cache, but can we also keep an
+@struct{inode_disk} inside @struct{file}, the way the provided code
+does?}
+
+The goal of the 64-block limit is to bound the amount of cached file
+system data.  If you keep a block of disk data anywhere in kernel
+memory, whether it's file data or metadata, then you have to count it
+against the 64-block limit.  The same rule applies to anything that's
+``similar'' to a block of disk data, such as a @struct{inode_disk}
+without the @code{length} or @code{sector_cnt} members.
+
+That means you'll have to change the way the file implementation
+accesses its corresponding inode right now, since it currently just
+creates a new @struct{inode} containing an @struct{inode_disk} in
+@func{inode_open} and reads the corresponding sector in from disk when
+it's created.
+
+There are two reasons for not storing inode data in @struct{inode}.
 First, keeping extra copies of inodes would be cheating the 64-block
 limitation that we place on your cache.  Second, if two processes have
-the same file open, you will create a huge synchronization headache
-for yourself if each @code{struct file} has its own copy of the inode.
-
-Note that you can store pointers to inodes in @code{struct file} if
-you want, and you can store some other small amount of information to
-help you find the inode when you need it.
-
-Similarly, if you want to store one block of data plus some small
-amount of metadata for each of your 64 cache entries, that's fine.
-
-@item
-@b{But why can't we store copies of inodes in @code{struct file}? We
-don't understand the answer to the previous question.}
-
-The issue regarding storing @code{struct inode}s has to do with
-implementation of the buffer cache.  Basically, you can't store a
-@code{struct inode *} in @code{struct inode}.  Each time you need
-to read a @code{struct inode}, you'll have to get it either from the
-buffer cache or from disk.
-
-If you look at @code{file_read_at()}, it uses the inode directly
-without having first read in that sector from wherever it was in the
-storage hierarchy.  You are no longer allowed to do this.  You will
-need to change @code{file_read_at} (and similar functions) so that it
-reads the inode from the storage hierarchy before using it.
+the same file open, you will create a huge synchronization headache for
+yourself if each @struct{inode} has its own copy of the on-disk inode.
+
+You can store pointers to inode data in @struct{inode_disk}, if you
+want, and you can store some other small amount of information to help
+you find the inode when you need it.  Similarly, if you want to store
+one block of data plus some small amount of metadata for each of your 64
+cache entries, that's fine.
+
+If you look at @func{file_read_at}, it uses the inode directly without
+having first read in that sector from wherever it was in the storage
+hierarchy.  This will no longer work.  You will need to change
+@code{file_read_at} (and similar functions) so that it reads the inode
+from the storage hierarchy before using it.
 @end enumerate