d0e5c496c2c0af8cb7e5c6ee57807b0c7c258869
[pintos-anon] / src / filesys / filesys.c
1 #include "filesys.h"
2 #include "disk.h"
3 #include "directory.h"
4
5 static struct disk *disk;
6
7 static struct file free_map_file, root_dir_file;
8
9 #define FREE_MAP_SECTOR 0
10 #define ROOT_DIR_SECTOR 1
11
12 #define NUM_DIR_ENTRIES 10
13 #define ROOT_DIR_FILE_SIZE (sizeof (struct dir_entry) * NUM_DIR_ENTRIES)
14
15 static void
16 do_format (void)
17 {
18   struct bitmap free_map;
19   struct filehdr map_hdr, dir_hdr;
20   struct dir dir;
21
22   /* Create the initial bitmap and reserve sectors for the
23      free map and root directory file headers. */
24   if (!bitmap_init (&free_map, disk_size (disk)))
25     panic ("bitmap creation failed");
26   bitmap_mark (&free_map, FREE_MAP_SECTOR);
27   bitmap_mark (&free_map, ROOT_DIR_SECTOR);
28
29   /* Allocate data sector(s) for the free map file
30      and write its file header to disk. */
31   if (!filehdr_allocate (&map_hdr, bitmap_storage_size (&free_map)))
32     panic ("free map creation failed");
33   filehdr_write (&map_hdr, FREE_MAP_SECTOR);
34   filehdr_destroy (&map_hdr);
35
36   /* Allocate data sector(s) for the root directory file
37      and write its file header to disk. */
38   if (!filehdr_allocate (&dir_hdr, ROOT_DIR_FILE_SIZE))
39     panic ("root directory creation failed");
40   filehdr_write (&dir_hdr, FREE_MAP_SECTOR);
41   filehdr_destroy (&dir_hdr);
42
43   /* Write out the free map now that we have space reserved
44      for it. */
45   file_open (&free_map_file, FREE_MAP_SECTOR);
46   bitmapio_write (&free_map, free_map_file);
47   bitmap_destroy (&free_map);
48   file_close (&free_map_file);
49
50   /* Write out the root directory in the same way. */
51   file_open (&root_dir_file, ROOT_DIR_SECTOR);
52   if (!dir_init (&dir, NUM_DIR_ENTRIES))
53     panic ("can't initialize root directory");
54   dir_write (root_dir_file);
55   dir_destroy (&dir);
56   file_close (&free_map_file);
57 }
58
59 void
60 filesys_init (bool format) 
61 {
62   disk = disk_get (1);
63   if (disk == NULL)
64     panic ("ide1:1 not present, filesystem initialization failed");
65
66   if (format) 
67     do_format ();
68   
69   file_open (&free_map_file, FREE_MAP_SECTOR);
70   file_open (&root_dir_file, ROOT_DIR_SECTOR);
71 }
72
73 bool
74 filesys_create (const char *name, off_t initial_size) 
75 {
76   struct dir dir;
77   struct bitmap free_map;
78   disk_sector_no hdr_sector;
79   struct filehdr filehdr;
80   bool success = false;
81
82   /* Read the root directory. */
83   dir_init (&dir, NUM_DIR_ENTRIES);
84   dir_read (&dir, &root_dir_file);
85   if (dir_lookup (&dir, name, NULL)) 
86     goto exit1;
87
88   /* Allocate a block for the file header. */
89   if (!bitmap_init (&free_map, disk_size (disk)))
90     goto exit1;
91   bitmapio_read (&free_map, &free_map_file);
92   hdr_sector = bitmap_find_and_set (&free_map);
93   if (hdr_sector == BITMAP_ERROR)
94     goto exit2;
95
96   /* Add the file to the directory. */
97   if (!dir_add (&dir, name, hdr_sector))
98     goto exit2;
99
100   /* Allocate space for the file. */
101   if (!filehdr_allocate (&filehdr, initial_size))
102     goto exit2;
103
104   /* Write everything back. */
105   filehdr_write (&filehdr, hdr_sector);
106   dir_write (&dir, &root_dir_file);
107   bitmapio_write (&free_map, &free_map_file);
108
109   success = true;
110
111   /* Clean up. */
112   filehdr_destroy (&filehdr);
113  exit2:
114   bitmap_destroy (&free_map);
115  exit1:
116   dir_destroy (&dir);
117
118   return success;
119 }
120
121 bool
122 filesys_remove (const char *name) 
123 {
124   struct dir dir;
125   disk_sector_no hdr_sector;
126   struct filehdr filehdr;
127   struct bitmap free_map;
128   bool success = false;
129
130   /* Read the root directory. */
131   dir_init (&dir, NUM_DIR_ENTRIES);
132   dir_read (&dir, &root_dir_file);
133   if (!dir_lookup (&dir, name, &hdr_sector))
134     goto exit1;
135
136   /* Read the file header. */
137   if (!filehdr_read (&filehdr, hdr_sector))
138     goto exit1;
139
140   /* Allocate a block for the file header. */
141   if (!bitmap_init (&free_map, disk_size (disk)))
142     goto exit2;
143   bitmapio_read (&free_map, &free_map_file);
144
145   /* Deallocate. */
146   filehdr_deallocate (&filehdr, &free_map);
147   bitmap_reset (&free_map, hdr_sector);
148   dir_remove (&dir, name);
149
150   /* Write everything back. */
151   bitmapio_write (&free_map, &free_map_file);
152   dir_write (&dir, &root_dir_file);
153
154   success = true;
155
156   /* Clean up. */
157   bitmap_destroy (&free_map);
158  exit2:
159   filehdr_destroy (&filehdr);
160  exit1:
161   dir_destroy (&dir);
162
163   return success;
164 }
165
166 #undef NDEBUG
167 #include "debug.h"
168 #include "file.h"
169
170 void
171 filesys_self_test (void)
172 {
173   static const char s[] = "This is a test string.";
174   struct file *file;
175   char s2[sizeof s];
176
177   ASSERT (filesys_create ("foo"));
178   ASSERT ((file = filesys_open ("foo")) != NULL);
179   ASSERT (file_write (file, s, sizeof s) == sizeof s);
180   ASSERT (file_tell (file) == sizeof s);
181   ASSERT (file_length (file) == sizeof s);
182   file_close (file);
183
184   ASSERT ((file = filesys_open ("foo")) != NULL);
185   ASSERT (file_read (file, s2, sizeof s2) == sizeof s2);
186   ASSERT (memcmp (s, s2, sizeof s) == 0);
187   ASSERT (file_tell (file) == sizeof s2);
188   ASSERT (file_length (file) == sizeof s2);
189   file_close (file);
190
191   ASSERT (filesys_remove ("foo"));
192 }