X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Fdirectory.c;h=fd1590254a65a30acf6b150777cd7c8d316ba61c;hb=3c4ff7ffae2e6f05a2c78ec77814dbc5a98c4f98;hp=93a505b2424500f12c24087dcf01b20efd61d6ef;hpb=9fe3c2a0f3ba65c470d726e99d54e8337eb4e0da;p=pintos-anon diff --git a/src/filesys/directory.c b/src/filesys/directory.c index 93a505b..fd15902 100644 --- a/src/filesys/directory.c +++ b/src/filesys/directory.c @@ -1,41 +1,86 @@ -#include "directory.h" -#include "file.h" -#include "fsutil.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) { @@ -44,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++) @@ -56,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; @@ -68,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; @@ -85,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 (*name == '\0' || strlen (name) > NAME_MAX) + return false; + for (i = 0; i < d->entry_cnt; i++) { struct dir_entry *e = &d->entries[i]; @@ -92,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) { @@ -117,6 +178,7 @@ dir_remove (struct dir *d, const char *name) return false; } +/* Prints the names of the files in D to the system console. */ void dir_list (const struct dir *d) { @@ -124,19 +186,5 @@ dir_list (const struct dir *d) for (e = d->entries; e < d->entries + d->entry_cnt; e++) if (e->in_use) - printk ("%s\n", e->name); -} - -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) - { - printk ("Contents of %s:\n", e->name); - fsutil_print (e->name); - printk ("\n"); - } + printf ("%s\n", e->name); }