X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Ffile.c;h=e6f282f8062dc2c383f3a540c08b73d0a9628ce7;hb=2cf38a4ba2dd965c892767b0d8ee97e67f33b274;hp=0c18ab093dab78aea95471da9f4bd14a1f3b3c92;hpb=04584a49656ea770c77e3eee9537e1b726118cb6;p=pintos-anon diff --git a/src/filesys/file.c b/src/filesys/file.c index 0c18ab0..e6f282f 100644 --- a/src/filesys/file.c +++ b/src/filesys/file.c @@ -6,53 +6,126 @@ #include "lib.h" #include "malloc.h" +bool +file_open (struct file *file, const char *name) +{ + struct dir dir; + disk_sector_no hdr_sector; + bool success = false; + + dir_init (&dir, NUM_DIR_ENTRIES); + dir_read (&dir, &root_dir_file); + if (dir_lookup (&dir, name, &hdr_sector)) + success = file_open_sector (file, hdr_sector); + + dir_destroy (&dir); + return success; +} + +bool +file_open_sector (struct file *file, disk_sector_no hdr_sector) +{ + file->pos = 0; + return filehdr_read (&file->hdr, hdr_sector); +} + void file_close (struct file *file) { - filesys_stub_lock (); - filesys_stub_put_string ("close"); - filesys_stub_put_file (file); - filesys_stub_match_string ("close"); - filesys_stub_unlock (); + filehdr_destroy (file); } off_t file_read (struct file *file, void *buffer, off_t size) { - int32_t retval; + off_t retval = file_read_at (file, buffer, size, file->pos); + file->pos += retval; + return retval; +} - filesys_stub_lock (); - filesys_stub_put_string ("read"); - filesys_stub_put_file (file); - filesys_stub_put_uint32 (size); - filesys_stub_match_string ("read"); - retval = filesys_stub_get_int32 (); - if (retval > 0) +off_t +file_read_at (struct file *file, void *buffer_, off_t size, off_t start) +{ + uint8_t *buffer = buffer_; + off_t bytes_read = 0; + uint8_t *bounce; + + bounce = malloc (DISK_SECTOR_SIZE); + while (size > 0) { - ASSERT (retval <= size); - filesys_stub_get_bytes (buffer, retval); + /* Disk sector to read, starting byte offset within sector. */ + off_t sector_idx = filehdr_byte_to_sector (file->hdr); + int sector_ofs = start % DISK_SECTOR_SIZE; + + /* Bytes left in file, bytes left in sector. */ + off_t file_left = filehdr_size (file->hdr) - start; + off_t sector_left = DISK_SECTOR_SIZE - sector_ofs; + + /* Number of bytes to actually copy out of this sector. */ + int chunk_size = file_left < sector_left ? file_left : sector_left; + if (chunk_size == 0) + break; + + /* Read sector into bounce buffer, then copy into caller's + buffer. */ + disk_read (disk, sector_idx, bounce); + memcpy (buffer + bytes_read, bounce + sector_ofs, chunk_size); + + /* Advance. */ + size -= chunk_size; + start += chunk_size; + bytes_read += chunk_size; } - filesys_stub_unlock (); - - return retval; + free (bounce); + + return bytes_read; } off_t file_write (struct file *file, const void *buffer, off_t size) { - int32_t retval; + off_t retval = file_write_at (file, buffer, size, file->pos); + file->pos += retval; + return retval; +} - filesys_stub_lock (); - filesys_stub_put_string ("write"); - filesys_stub_put_file (file); - filesys_stub_put_uint32 (size); - filesys_stub_put_bytes (buffer, size); - filesys_stub_match_string ("write"); - retval = filesys_stub_get_int32 (); - ASSERT (retval <= size); - filesys_stub_unlock (); +off_t +file_write_at (struct file *file, const void *buffer_, off_t size, + off_t start) +{ + uint8_t *buffer = buffer_; + off_t bytes_read = 0; + uint8_t *bounce; - return retval; + bounce = malloc (DISK_SECTOR_SIZE); + while (size > 0) + { + /* Disk sector to read, starting byte offset within sector. */ + off_t sector_idx = filehdr_byte_to_sector (file->hdr); + int sector_ofs = start % DISK_SECTOR_SIZE; + + /* Bytes left in file, bytes left in sector. */ + off_t file_left = filehdr_size (file->hdr) - start; + off_t sector_left = DISK_SECTOR_SIZE - sector_ofs; + + /* Number of bytes to actually copy out of this sector. */ + int chunk_size = file_left < sector_left ? file_left : sector_left; + if (chunk_size == 0) + break; + + /* Read sector into bounce buffer, then copy into caller's + buffer. */ + disk_read (disk, sector_idx, bounce); + memcpy (buffer + bytes_read, bounce + sector_ofs, chunk_size); + + /* Advance. */ + size -= chunk_size; + start += chunk_size; + bytes_read += chunk_size; + } + free (bounce); + + return bytes_read; } off_t