X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Ffsutil.c;h=cc0e33500eb2a6ffad699e4342cd84cc40d22bf8;hb=5626572820d71c9af988aeb4326dd2c2ac6909ca;hp=57cd4e8d5d2024faf3c21eed04ca1ec2819dae2c;hpb=4e56c3db3a372c96da21981f270a791e29452039;p=pintos-anon diff --git a/src/filesys/fsutil.c b/src/filesys/fsutil.c index 57cd4e8..cc0e335 100644 --- a/src/filesys/fsutil.c +++ b/src/filesys/fsutil.c @@ -1,38 +1,57 @@ -#include "fsutil.h" +#include "filesys/fsutil.h" +#include #include -#include "debug.h" -#include "filesys.h" -#include "file.h" -#include "lib.h" -#include "mmu.h" -#include "palloc.h" - -char *fsutil_copy_arg; +#include +#include +#include +#include "filesys/file.h" +#include "filesys/filesys.h" +#include "threads/mmu.h" +#include "threads/palloc.h" + +/* Destination filename and size for copy-in operations. */ +char *fsutil_copyin_file; +int fsutil_copyin_size; + +/* Source filename for copy-out operations. */ +char *fsutil_copyout_file; + +/* Name of a file print to print to console. */ char *fsutil_print_file; + +/* Name of a file to delete. */ char *fsutil_remove_file; + +/* List all files in the filesystem to the system console? */ bool fsutil_list_files; + +/* Dump full contents of filesystem to the system console? */ bool fsutil_dump_filesys; +/* Copies from the "scratch" disk, hdc or hd1:0, + to a file named FILENAME in the filesystem. + The file will be SIZE bytes in length. */ static void -copy (const char *filename, off_t size) +copy_in (const char *filename, off_t size) { struct disk *src; - struct file dst; - disk_sector_no sector; + struct file *dst; + disk_sector_t sector; void *buffer; /* Open source disk. */ - src = disk_get (2); + src = disk_get (1, 0); if (src == NULL) - PANIC ("couldn't open source disk (hdc or ide1:0)"); + PANIC ("couldn't open source disk (hdc or hd1:0)"); if (size > (off_t) disk_size (src) * DISK_SECTOR_SIZE) - PANIC ("source disk is too small for %Ld-byte file", + PANIC ("source disk is too small for %lld-byte file", (unsigned long long) size); /* Create destination file. */ if (!filesys_create (filename, size)) PANIC ("%s: create failed", filename); - if (!filesys_open (filename, &dst)) + dst = filesys_open (filename); + if (dst == NULL) PANIC ("%s: open failed", filename); /* Do copy. */ @@ -42,30 +61,75 @@ copy (const char *filename, off_t size) { int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size; disk_read (src, sector++, buffer); - if (file_write (&dst, buffer, chunk_size) != chunk_size) - PANIC ("%s: write failed with %Ld bytes unwritten", + if (file_write (dst, buffer, chunk_size) != chunk_size) + PANIC ("%s: write failed with %lld bytes unwritten", filename, (unsigned long long) size); size -= chunk_size; } palloc_free (buffer); - file_close (&dst); + file_close (dst); } -void -fsutil_run (void) +/* Copies FILENAME from the file system to the scratch disk. + The first four bytes of the first sector in the disk + receive the file's size in bytes as a little-endian integer. + The second and subsequent sectors receive the file's data. */ +static void +copy_out (const char *filename) { - if (fsutil_copy_arg != NULL) - { - char *save; - char *filename = strtok_r (fsutil_copy_arg, ":", &save); - char *size = strtok_r (NULL, "", &save); + void *buffer; + struct file *src; + struct disk *dst; + off_t size; + disk_sector_t sector; - if (filename == NULL || size == NULL) - PANIC ("bad format for -cp option; use -u for usage"); + buffer = palloc_get (PAL_ASSERT | PAL_ZERO); - copy (filename, atoi (size)); + /* Open source file. */ + src = filesys_open (filename); + if (src == NULL) + PANIC ("%s: open failed", filename); + size = file_length (src); + + /* Open target disk. */ + dst = disk_get (1, 0); + if (dst == NULL) + PANIC ("couldn't open target disk (hdc or hd1:0)"); + if (size + DISK_SECTOR_SIZE > (off_t) disk_size (dst) * DISK_SECTOR_SIZE) + PANIC ("target disk is too small for %lld-byte file", + (unsigned long long) size); + + /* Write size to sector 0. */ + *(uint32_t *) buffer = size; + disk_write (dst, 0, buffer); + + /* Do copy. */ + sector = 1; + while (size > 0) + { + int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size; + if (file_read (src, buffer, chunk_size) != chunk_size) + PANIC ("%s: read failed with %lld bytes unread", + filename, (unsigned long long) size); + disk_write (dst, sector++, buffer); + size -= chunk_size; } + palloc_free (buffer); + + file_close (src); +} + +/* Executes the filesystem operations described by the variables + declared in fsutil.h. */ +void +fsutil_run (void) +{ + if (fsutil_copyin_file != NULL) + copy_in (fsutil_copyin_file, fsutil_copyin_size); + + if (fsutil_copyout_file != NULL) + copy_out (fsutil_copyout_file); if (fsutil_print_file != NULL) fsutil_print (fsutil_print_file); @@ -73,7 +137,7 @@ fsutil_run (void) if (fsutil_remove_file != NULL) { if (filesys_remove (fsutil_remove_file)) - printk ("%s: removed\n", fsutil_remove_file); + printf ("%s: removed\n", fsutil_remove_file); else PANIC ("%s: remove failed\n", fsutil_remove_file); } @@ -85,23 +149,26 @@ fsutil_run (void) filesys_dump (); } +/* Prints the contents of file FILENAME to the system console as + hex and ASCII. */ void fsutil_print (const char *filename) { - struct file file; + struct file *file; char *buffer; - if (!filesys_open (filename, &file)) + file = filesys_open (filename); + if (file == NULL) PANIC ("%s: open failed", filename); buffer = palloc_get (PAL_ASSERT); for (;;) { - off_t n = file_read (&file, buffer, PGSIZE); + off_t n = file_read (file, buffer, PGSIZE); if (n == 0) break; - hex_dump (buffer, n, true); + hex_dump (0, buffer, n, true); } palloc_free (buffer); - file_close (&file); + file_close (file); }