1 #include "filesys/fsutil.h"
7 #include "filesys/file.h"
8 #include "filesys/filesys.h"
9 #include "devices/partition.h"
10 #include "threads/mmu.h"
11 #include "threads/palloc.h"
13 /* Destination filename and size for copy-in operations. */
14 char *fsutil_copyin_file;
15 int fsutil_copyin_size;
17 /* Source filename for copy-out operations. */
18 char *fsutil_copyout_file;
20 /* Name of a file print to print to console. */
21 char *fsutil_print_file;
23 /* Name of a file to delete. */
24 char *fsutil_remove_file;
26 /* List all files in the file system to the system console? */
27 bool fsutil_list_files;
29 /* Dump full contents of file system to the system console? */
30 bool fsutil_dump_filesys;
32 /* Copies from the "scratch" disk, hdc or hd1:0,
33 to a file named FILENAME in the file system.
34 The file will be SIZE bytes in length. */
36 copy_in (const char *filename, off_t size)
38 struct partition *src;
43 /* Open scratch partition. */
44 src = partition_get (PARTITION_SCRATCH);
46 PANIC ("couldn't open scratch partition");
47 if (size > (off_t) partition_size (src) * DISK_SECTOR_SIZE)
48 PANIC ("scratch partition is too small for %lld-byte file",
49 (unsigned long long) size);
51 /* Create destination file. */
52 if (!filesys_create (filename, size))
53 PANIC ("%s: create failed", filename);
54 dst = filesys_open (filename);
56 PANIC ("%s: open failed", filename);
59 buffer = palloc_get_page (PAL_ASSERT);
63 int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
64 partition_read (src, sector++, buffer);
65 if (file_write (dst, buffer, chunk_size) != chunk_size)
66 PANIC ("%s: write failed with %lld bytes unwritten",
67 filename, (unsigned long long) size);
70 palloc_free_page (buffer);
75 /* Copies FILENAME from the file system to the scratch disk.
76 The first four bytes of the first sector in the disk
77 receive the file's size in bytes as a little-endian integer.
78 The second and subsequent sectors receive the file's data. */
80 copy_out (const char *filename)
84 struct partition *dst;
88 buffer = palloc_get_page (PAL_ASSERT | PAL_ZERO);
90 /* Open source file. */
91 src = filesys_open (filename);
93 PANIC ("%s: open failed", filename);
94 size = file_length (src);
96 /* Open target partition. */
97 dst = partition_get (PARTITION_SCRATCH);
99 PANIC ("couldn't open scratch partition");
100 if (size + DISK_SECTOR_SIZE
101 > (off_t) partition_size (dst) * DISK_SECTOR_SIZE)
102 PANIC ("scratch partition is too small for %lld-byte file",
103 (unsigned long long) size);
105 /* Write size to sector 0. */
106 *(uint32_t *) buffer = size;
107 partition_write (dst, 0, buffer);
113 int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
114 if (file_read (src, buffer, chunk_size) != chunk_size)
115 PANIC ("%s: read failed with %lld bytes unread",
116 filename, (unsigned long long) size);
117 partition_write (dst, sector++, buffer);
120 palloc_free_page (buffer);
125 /* Executes the file system operations described by the variables
126 declared in fsutil.h. */
130 if (fsutil_copyin_file != NULL)
131 copy_in (fsutil_copyin_file, fsutil_copyin_size);
133 if (fsutil_copyout_file != NULL)
134 copy_out (fsutil_copyout_file);
136 if (fsutil_print_file != NULL)
137 fsutil_print (fsutil_print_file);
139 if (fsutil_remove_file != NULL)
141 if (filesys_remove (fsutil_remove_file))
142 printf ("%s: removed\n", fsutil_remove_file);
144 PANIC ("%s: remove failed\n", fsutil_remove_file);
147 if (fsutil_list_files)
150 if (fsutil_dump_filesys)
154 /* Prints the contents of file FILENAME to the system console as
157 fsutil_print (const char *filename)
162 file = filesys_open (filename);
164 PANIC ("%s: open failed", filename);
165 buffer = palloc_get_page (PAL_ASSERT);
168 off_t n = file_read (file, buffer, PGSIZE);
172 hex_dump (0, buffer, n, true);
174 palloc_free_page (buffer);