X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Ffilesys.c;h=5cf1d974013a008705a91a9b4bd74855416e1967;hb=a4613d70fb56b93216299f6253698ab0e4bbd46d;hp=f8348ed2a2eaf4f17182507a9aebce1c47564966;hpb=3fc16f6e9abc98a3bd5427eb210669860609a224;p=pintos-anon diff --git a/src/filesys/filesys.c b/src/filesys/filesys.c index f8348ed..5cf1d97 100644 --- a/src/filesys/filesys.c +++ b/src/filesys/filesys.c @@ -1,90 +1,163 @@ -#include "filesys.h" +#include "filesys/filesys.h" +#include +#include +#include +#include "filesys/file.h" +#include "filesys/free-map.h" +#include "filesys/inode.h" +#include "filesys/directory.h" +#include "devices/disk.h" + +/* The disk that contains the filesystem. */ +struct disk *filesys_disk; + +static void do_format (void); + +/* Initializes the filesystem module. + If FORMAT is true, reformats the filesystem. */ +void +filesys_init (bool format) +{ + filesys_disk = disk_get (0, 1); + if (filesys_disk == NULL) + PANIC ("hd0:1 (hdb) not present, filesystem initialization failed"); + inode_init (); + free_map_init (); -#ifdef FILESYS_STUB -#include -#include "debug.h" -#include "filesys-stub.h" -#include "lib.h" + if (format) + do_format (); + + free_map_open (); +} +/* Shuts down the filesystem module, writing any unwritten data + to disk. */ void -filesys_init (bool reformat) +filesys_done (void) { - if (reformat) - printk ("filesystem stubs don't support formatting\n"); - filesys_stub_init (); + free_map_close (); } - + +/* Creates a file named NAME with the given INITIAL_SIZE. + Returns true if successful, false otherwise. + Fails if a file named NAME already exists, + or if internal memory allocation fails. */ bool -filesys_create (const char *name) +filesys_create (const char *name, off_t initial_size) { - bool success; - - filesys_stub_lock (); - filesys_stub_put_string ("create"); - filesys_stub_put_string (name); - filesys_stub_match_string ("create"); - success = filesys_stub_get_bool (); - filesys_stub_unlock (); + disk_sector_t inode_sector = 0; + struct dir *dir = dir_open_root (); + bool success = (dir != NULL + && free_map_allocate (1, &inode_sector) + && inode_create (inode_sector, initial_size) + && dir_add (dir, name, inode_sector)); + if (!success && inode_sector != 0) + free_map_release (inode_sector, 1); + dir_close (dir); return success; } +/* Opens the file with the given NAME. + Returns the new file if successful or a null pointer + otherwise. + Fails if no file named NAME exists, + or if an internal memory allocation fails. */ struct file * -filesys_open (const char *name) +filesys_open (const char *name) { - struct file *file; + struct dir *dir = dir_open_root (); + struct inode *inode = NULL; - filesys_stub_lock (); - filesys_stub_put_string ("open"); - filesys_stub_put_string (name); - filesys_stub_match_string ("open"); - file = filesys_stub_get_file (); - filesys_stub_unlock (); - - return file; + if (dir != NULL) + dir_lookup (dir, name, &inode); + dir_close (dir); + + return file_open (inode); } +/* Deletes the file named NAME. + Returns true if successful, false on failure. + Fails if no file named NAME exists, + or if an internal memory allocation fails. */ bool filesys_remove (const char *name) { - bool success; - - filesys_stub_lock (); - filesys_stub_put_string ("remove"); - filesys_stub_put_string (name); - filesys_stub_match_string ("remove"); - success = filesys_stub_get_bool (); - filesys_stub_unlock (); + struct dir *dir = dir_open_root (); + bool success = dir != NULL && dir_remove (dir, name); + dir_close (dir); return success; } -#endif /* FILESYS_STUB */ - -#undef NDEBUG -#include "debug.h" -#include "file.h" + +static void must_succeed_function (int, bool) NO_INLINE; +#define MUST_SUCCEED(EXPR) must_succeed_function (__LINE__, EXPR) +/* Performs basic sanity checks on the filesystem. + The filesystem should not contain a file named `foo' when + called. */ void filesys_self_test (void) { static const char s[] = "This is a test string."; + static const char zeros[sizeof s] = {0}; struct file *file; char s2[sizeof s]; + int i; + + filesys_remove ("foo"); + for (i = 0; i < 2; i++) + { + /* Create file and check that it contains zeros + throughout the created length. */ + MUST_SUCCEED (filesys_create ("foo", sizeof s)); + MUST_SUCCEED ((file = filesys_open ("foo")) != NULL); + MUST_SUCCEED (file_read (file, s2, sizeof s2) == sizeof s2); + MUST_SUCCEED (memcmp (s2, zeros, sizeof s) == 0); + MUST_SUCCEED (file_tell (file) == sizeof s); + MUST_SUCCEED (file_length (file) == sizeof s); + file_close (file); + + /* Reopen file and write to it. */ + MUST_SUCCEED ((file = filesys_open ("foo")) != NULL); + MUST_SUCCEED (file_write (file, s, sizeof s) == sizeof s); + MUST_SUCCEED (file_tell (file) == sizeof s); + MUST_SUCCEED (file_length (file) == sizeof s); + file_close (file); + + /* Reopen file and verify that it reads back correctly. + Delete file while open to check proper semantics. */ + MUST_SUCCEED ((file = filesys_open ("foo")) != NULL); + MUST_SUCCEED (filesys_remove ("foo")); + MUST_SUCCEED (filesys_open ("foo") == NULL); + MUST_SUCCEED (file_read (file, s2, sizeof s) == sizeof s); + MUST_SUCCEED (memcmp (s, s2, sizeof s) == 0); + MUST_SUCCEED (file_tell (file) == sizeof s); + MUST_SUCCEED (file_length (file) == sizeof s); + file_close (file); + } + + printf ("filesys: self test ok\n"); +} - ASSERT (filesys_create ("foo")); - ASSERT ((file = filesys_open ("foo")) != NULL); - ASSERT (file_write (file, s, sizeof s) == sizeof s); - ASSERT (file_tell (file) == sizeof s); - ASSERT (file_length (file) == sizeof s); - file_close (file); - - ASSERT ((file = filesys_open ("foo")) != NULL); - ASSERT (file_read (file, s2, sizeof s2) == sizeof s2); - ASSERT (memcmp (s, s2, sizeof s) == 0); - ASSERT (file_tell (file) == sizeof s2); - ASSERT (file_length (file) == sizeof s2); - file_close (file); - - ASSERT (filesys_remove ("foo")); +/* If SUCCESS is false, panics with an error complaining about + LINE_NO. */ +static void +must_succeed_function (int line_no, bool success) +{ + if (!success) + PANIC ("filesys_self_test: operation failed on line %d", line_no); +} + +/* Formats the filesystem. */ +static void +do_format (void) +{ + printf ("Formatting filesystem..."); + free_map_create (); + if (!dir_create (ROOT_DIR_SECTOR, 16)) + PANIC ("root directory creation failed"); + free_map_close (); + printf ("done.\n"); }