X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Fdirectory.c;h=ec6ecd98715d30ba99acff1449e15b0d440c92ea;hb=993c1d9f4452e2edd851f3175dfdf317f18bdb9f;hp=43f87f0e13e59b2b85afd92ef4da2bba72b5bd31;hpb=621963e2a383d53b2c5eca627102625421b46545;p=pintos-anon diff --git a/src/filesys/directory.c b/src/filesys/directory.c index 43f87f0..ec6ecd9 100644 --- a/src/filesys/directory.c +++ b/src/filesys/directory.c @@ -1,40 +1,86 @@ -#include "directory.h" -#include "file.h" -#include "lib.h" -#include "malloc.h" - -bool -dir_init (struct dir *d, size_t entry_cnt) +#include "filesys/directory.h" +#include +#include +#include "filesys/file.h" +#include "filesys/fsutil.h" +#include "threads/malloc.h" + +/* A directory. */ +struct dir + { + size_t entry_cnt; /* Number of entries. */ + struct dir_entry *entries; /* Array of entries. */ + }; + +/* A single directory entry. */ +struct dir_entry + { + bool in_use; /* In use or free? */ + char name[NAME_MAX + 1]; /* Null terminated file name. */ + disk_sector_t inode_sector; /* Sector number of header. */ + }; + +/* Returns a new directory that holds ENTRY_CNT entries, if + successful, or a null pointer if memory is unavailable. */ +struct dir * +dir_create (size_t entry_cnt) { - d->entry_cnt = entry_cnt; - d->entries = calloc (1, sizeof *d->entries * entry_cnt); - return d->entries != NULL; + struct dir *d = malloc (sizeof *d); + if (d != NULL) + { + d->entry_cnt = entry_cnt; + d->entries = calloc (1, sizeof *d->entries * entry_cnt); + if (d->entries != NULL) + return d; + free (d); + } + return NULL; } -void -dir_destroy (struct dir *d) +/* Returns the size, in bytes, of a directory with ENTRY_CNT + entries. */ +size_t +dir_size (size_t entry_cnt) { - free (d->entries); + return entry_cnt * sizeof (struct dir_entry); } -static off_t -dir_size (struct dir *d) +/* Destroys D and frees associated resources. */ +void +dir_destroy (struct dir *d) { - return d->entry_cnt * sizeof *d->entries; + if (d != NULL) + { + free (d->entries); + free (d); + } } +/* Reads D from FILE. + D must have already been initialized, to the correct number of + entries, with dir_init(). */ void dir_read (struct dir *d, struct file *file) { - file_read_at (file, d->entries, dir_size (d), 0); + ASSERT (d != NULL); + ASSERT (file != NULL); + ASSERT (file_length (file) >= (off_t) dir_size (d->entry_cnt)); + + file_read_at (file, d->entries, dir_size (d->entry_cnt), 0); } +/* Writes D to FILE. + D must have already been initialized, to the correct number of + entries, with dir_init(). */ void dir_write (struct dir *d, struct file *file) { - file_write_at (file, d->entries, dir_size (d), 0); + file_write_at (file, d->entries, dir_size (d->entry_cnt), 0); } +/* Searches D for a file named NAME. + If successful, returns the file's entry; + otherwise, returns a null pointer. */ static struct dir_entry * lookup (const struct dir *d, const char *name) { @@ -43,7 +89,7 @@ lookup (const struct dir *d, const char *name) ASSERT (d != NULL); ASSERT (name != NULL); - if (strlen (name) > FILENAME_LEN_MAX) + if (strlen (name) > NAME_MAX) return NULL; for (i = 0; i < d->entry_cnt; i++) @@ -55,9 +101,13 @@ lookup (const struct dir *d, const char *name) return NULL; } +/* Searches D for a file named NAME + and returns true if one exists, false otherwise. + If INODE_SECTOR is nonnull, then on success *INODE_SECTOR + is set to the sector that contains the file's inode. */ bool dir_lookup (const struct dir *d, const char *name, - disk_sector_no *filehdr_sector) + disk_sector_t *inode_sector) { const struct dir_entry *e; @@ -67,16 +117,22 @@ dir_lookup (const struct dir *d, const char *name, e = lookup (d, name); if (e != NULL) { - if (filehdr_sector != NULL) - *filehdr_sector = e->filehdr_sector; + if (inode_sector != NULL) + *inode_sector = e->inode_sector; return true; } else return false; } +/* Adds a file named NAME to D, which must not already contain a + file by that name. The file's inode is in sector + INODE_SECTOR. + Returns true if successful, false on failure. + Fails if NAME is invalid (i.e. too long) or if D has no free + directory entries. */ bool -dir_add (struct dir *d, const char *name, disk_sector_no filehdr_sector) +dir_add (struct dir *d, const char *name, disk_sector_t inode_sector) { size_t i; @@ -84,6 +140,9 @@ dir_add (struct dir *d, const char *name, disk_sector_no filehdr_sector) ASSERT (name != NULL); ASSERT (lookup (d, name) == NULL); + if (strlen (name) > NAME_MAX) + return false; + for (i = 0; i < d->entry_cnt; i++) { struct dir_entry *e = &d->entries[i]; @@ -91,13 +150,16 @@ dir_add (struct dir *d, const char *name, disk_sector_no filehdr_sector) { e->in_use = true; strlcpy (e->name, name, sizeof e->name); - e->filehdr_sector = filehdr_sector; + e->inode_sector = inode_sector; return true; } } return false; } +/* Removes any entry for NAME in D. + Returns true if successful, false on failure, + which occurs only if there is no file with the given NAME. */ bool dir_remove (struct dir *d, const char *name) { @@ -116,5 +178,29 @@ dir_remove (struct dir *d, const char *name) return false; } -void dir_list (const struct dir *); -void dir_print (const struct dir *); +/* Prints the names of the files in D to the system console. */ +void +dir_list (const struct dir *d) +{ + struct dir_entry *e; + + for (e = d->entries; e < d->entries + d->entry_cnt; e++) + if (e->in_use) + printf ("%s\n", e->name); +} + +/* Dumps the contents of D, including its files' names and their + contents, to the system console. */ +void +dir_dump (const struct dir *d) +{ + struct dir_entry *e; + + for (e = d->entries; e < d->entries + d->entry_cnt; e++) + if (e->in_use) + { + printf ("Contents of %s:\n", e->name); + fsutil_print (e->name); + printf ("\n"); + } +}