summaryrefslogtreecommitdiffstats
path: root/src/filesys/filesys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/filesys/filesys.c')
-rw-r--r--src/filesys/filesys.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/filesys/filesys.c b/src/filesys/filesys.c
index fedda08..d30f728 100644
--- a/src/filesys/filesys.c
+++ b/src/filesys/filesys.c
@@ -7,6 +7,11 @@
#include "filesys/inode.h"
#include "filesys/directory.h"
#include "devices/disk.h"
+#include "threads/synch.h"
+
+/* Locks filesys_create so the same file isn't
+ created twice with the same name. */
+static struct lock create_lock;
/* The disk that contains the file system. */
struct disk *filesys_disk;
@@ -22,6 +27,8 @@ filesys_init (bool format)
if (filesys_disk == NULL)
PANIC ("hd0:1 (hdb) not present, file system initialization failed");
+ lock_init (&create_lock);
+
inode_init ();
free_map_init ();
@@ -48,12 +55,14 @@ filesys_create (const char *name, off_t initial_size)
{
disk_sector_t inode_sector = 0;
struct dir *dir = dir_open_root ();
+ lock_acquire (&create_lock);
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);
+ && free_map_allocate (1, &inode_sector) // find sector
+ && inode_create (inode_sector, initial_size) // create inode pointing to sector
+ && dir_add (dir, name, inode_sector)); // add dir entry pointing to inode
+ lock_release (&create_lock);
+ if (!success && inode_sector != 0) // oops, we got a sector but file creation failed
+ free_map_release (inode_sector, 1); // so deallocate the sector
dir_close (dir);
return success;