X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilesys%2Ffsutil.c;h=0482f2da1dc58c99f8fa9ccaafa11829ec2e0272;hb=fba4443410241dd95c25a0fd7c5f8c0d8ff30ada;hp=659878510a338f7b2c3b17094493dd27bd75cc49;hpb=f6580e9ad405b519dbe85027691bf3c66074b0a4;p=pintos-anon diff --git a/src/filesys/fsutil.c b/src/filesys/fsutil.c index 6598785..0482f2d 100644 --- a/src/filesys/fsutil.c +++ b/src/filesys/fsutil.c @@ -1,15 +1,21 @@ -#include "fsutil.h" +#include "filesys/fsutil.h" +#include #include -#include "file.h" -#include "filesys.h" -#include "lib/debug.h" -#include "lib/lib.h" +#include +#include +#include +#include "filesys/file.h" +#include "filesys/filesys.h" +#include "devices/partition.h" #include "threads/mmu.h" #include "threads/palloc.h" -/* Filename and file size to use for copy operations, - as "filename:size". */ -char *fsutil_copy_arg; +/* 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; @@ -17,70 +23,115 @@ char *fsutil_print_file; /* Name of a file to delete. */ char *fsutil_remove_file; -/* List all files in the filesystem to the system console? */ +/* List all files in the file system to the system console? */ bool fsutil_list_files; -/* Dump full contents of filesystem to the system console? */ +/* Dump full contents of file system 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. + to a file named FILENAME in the file system. 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; + struct partition *src; + struct file *dst; disk_sector_t sector; void *buffer; - /* Open source disk. */ - src = disk_get (1, 0); + /* Open scratch partition. */ + src = partition_get (PARTITION_SCRATCH); if (src == NULL) - 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 %lld-byte file", + PANIC ("couldn't open scratch partition"); + if (size > (off_t) partition_size (src) * DISK_SECTOR_SIZE) + PANIC ("scratch partition 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. */ - buffer = palloc_get (PAL_ASSERT); + buffer = palloc_get_page (PAL_ASSERT); sector = 0; while (size > 0) { 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) + partition_read (src, sector++, buffer); + 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); + palloc_free_page (buffer); + + file_close (dst); +} + +/* 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) +{ + void *buffer; + struct file *src; + struct partition *dst; + off_t size; + disk_sector_t sector; + + buffer = palloc_get_page (PAL_ASSERT | PAL_ZERO); + + /* Open source file. */ + src = filesys_open (filename); + if (src == NULL) + PANIC ("%s: open failed", filename); + size = file_length (src); + + /* Open target partition. */ + dst = partition_get (PARTITION_SCRATCH); + if (dst == NULL) + PANIC ("couldn't open scratch partition"); + if (size + DISK_SECTOR_SIZE + > (off_t) partition_size (dst) * DISK_SECTOR_SIZE) + PANIC ("scratch partition is too small for %lld-byte file", + (unsigned long long) size); + + /* Write size to sector 0. */ + *(uint32_t *) buffer = size; + partition_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); + partition_write (dst, sector++, buffer); + size -= chunk_size; + } + palloc_free_page (buffer); - file_close (&dst); + file_close (src); } -/* Executes the filesystem operations described by the variables +/* Executes the file system operations described by the variables declared in fsutil.h. */ void fsutil_run (void) { - if (fsutil_copy_arg != NULL) - { - char *save; - char *filename = strtok_r (fsutil_copy_arg, ":", &save); - char *size = strtok_r (NULL, "", &save); - - if (filename == NULL || size == NULL) - PANIC ("bad format for -cp option; use -u for usage"); + if (fsutil_copyin_file != NULL) + copy_in (fsutil_copyin_file, fsutil_copyin_size); - copy (filename, atoi (size)); - } + if (fsutil_copyout_file != NULL) + copy_out (fsutil_copyout_file); if (fsutil_print_file != NULL) fsutil_print (fsutil_print_file); @@ -88,7 +139,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); } @@ -105,20 +156,21 @@ fsutil_run (void) 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); + buffer = palloc_get_page (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); + palloc_free_page (buffer); + file_close (file); }