/* Filesystem.
- For the purposes of the "user processes" assignment (project
- 2), please treat all the code in the filesys directory as a
- black box. No changes should be needed. For that project, a
- single lock external to the filesystem code suffices.
+ For the purposes of the "user processes" and "virtual memory"
+ assignments (projects 2 and 3), please treat all the code in
+ the filesys directory as a black box. No changes should be
+ needed. For those projects, a single lock external to the
+ filesystem code suffices.
The filesystem consists of a set of files. Each file has a
header called an `index node' or `inode', represented by
directory is represented as a file, the number of files
that may be created is also limited.
- - No indirect blocks. This limits maximum file size to the
- number of sector pointers that fit in a single inode
- times the size of a sector, or 126 * 512 == 63 kB given
- 32-bit sizes and 512-byte sectors.
+ - File data is allocated as a single extent, so that
+ external fragmentation can become a serious problem as a
+ file system is used over time.
- No subdirectories.
PANIC ("can't open root dir file");
}
+/* Shuts down the filesystem module, writing any unwritten data
+ to disk.
+ Currently there's nothing to do. You'll need to add code here
+ when you implement write-behind caching. */
+void
+filesys_done (void)
+{
+}
+
/* Creates a file named NAME with the given INITIAL_SIZE.
Returns true if successful, false otherwise.
Fails if a file named NAME already exists,
{
struct dir *dir = NULL;
struct bitmap *free_map = NULL;
- struct inode *inode = NULL;
disk_sector_t inode_sector;
bool success = false;
if (free_map == NULL)
goto done;
bitmap_read (free_map, free_map_file);
- inode_sector = bitmap_find_and_set (free_map);
+ inode_sector = bitmap_scan_and_flip (free_map, 0, 1, false);
if (inode_sector == BITMAP_ERROR)
goto done;
goto done;
/* Allocate space for the file. */
- inode = inode_create (free_map, inode_sector, initial_size);
- if (inode == NULL)
+ if (!inode_create (free_map, inode_sector, initial_size))
goto done;
/* Write everything back. */
- inode_commit (inode);
dir_write (dir, root_dir_file);
bitmap_write (free_map, free_map_file);
/* Clean up. */
done:
- inode_close (inode);
bitmap_destroy (free_map);
dir_destroy (dir);
/* Opens a file named NAME and initializes FILE for usage with
the file_*() functions declared in file.h.
- Returns true if successful, false on failure.
+ 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 *
if (!dir_lookup (dir, name, &inode_sector))
goto done;
- /* Open the inode and delete it it. */
+ /* Open the inode and delete it. */
inode = inode_open (inode_sector);
if (inode == NULL)
goto done;
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);
-
- /* Make sure file is deleted. */
- MUST_SUCCEED ((file = filesys_open ("foo")) == NULL);
}
printf ("filesys: self test ok\n");
do_format (void)
{
struct bitmap *free_map;
- struct inode *map_inode, *dir_inode;
struct dir *dir;
printf ("Formatting filesystem...");
bitmap_mark (free_map, FREE_MAP_SECTOR);
bitmap_mark (free_map, ROOT_DIR_SECTOR);
- /* Allocate data sector(s) for the free map file
- and write its inode to disk. */
- map_inode = inode_create (free_map, FREE_MAP_SECTOR,
- bitmap_file_size (free_map));
- if (map_inode == NULL)
+ /* Allocate free map and root dir files. */
+ if (!inode_create (free_map, FREE_MAP_SECTOR, bitmap_file_size (free_map)))
PANIC ("free map creation failed--disk is too large");
- inode_commit (map_inode);
- inode_close (map_inode);
-
- /* Allocate data sector(s) for the root directory file
- and write its inodes to disk. */
- dir_inode = inode_create (free_map, ROOT_DIR_SECTOR,
- dir_size (NUM_DIR_ENTRIES));
- if (dir_inode == NULL)
+ if (!inode_create (free_map, ROOT_DIR_SECTOR, dir_size (NUM_DIR_ENTRIES)))
PANIC ("root directory creation failed");
- inode_commit (dir_inode);
- inode_close (dir_inode);
/* Write out the free map now that we have space reserved
for it. */