1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include "filesys/filesys.h"
#include <debug.h>
#include <stdio.h>
#include <string.h>
#include "filesys/file.h"
#include "filesys/free-map.h"
#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;
static struct rwlock dir_lock; // dir_lookup and dir_remove
/* The disk that contains the file system. */
struct disk *filesys_disk;
static void do_format (void);
/* Initializes the file system module.
If FORMAT is true, reformats the file system. */
void
filesys_init (bool format)
{
filesys_disk = disk_get (0, 1);
if (filesys_disk == NULL)
PANIC ("hd0:1 (hdb) not present, file system initialization failed");
lock_init (&create_lock);
rwlock_init (&dir_lock);
inode_init ();
free_map_init ();
if (format)
do_format ();
free_map_open ();
}
/* Shuts down the file system module, writing any unwritten data
to disk. */
void
filesys_done (void)
{
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, 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) // 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;
}
/* 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)
{
struct dir *dir = dir_open_root ();
struct inode *inode = NULL;
if (dir != NULL) {
rwlock_read_p (&dir_lock);
dir_lookup (dir, name, &inode);
rwlock_read_v (&dir_lock);
}
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)
{
struct dir *dir = dir_open_root ();
rwlock_write_p (&dir_lock);
bool success = dir != NULL && dir_remove (dir, name);
rwlock_write_v (&dir_lock);
dir_close (dir);
return success;
}
/* Formats the file system. */
static void
do_format (void)
{
printf ("Formatting file system...");
free_map_create ();
if (!dir_create (ROOT_DIR_SECTOR, 16))
PANIC ("root directory creation failed");
free_map_close ();
printf ("done.\n");
}
|