1
+ use crate :: file_data_source:: FileDataSource ;
1
2
use anyhow:: Context ;
2
- use std:: { collections:: BTreeMap , fs, io, path:: Path } ;
3
+ use fatfs:: Dir ;
4
+ use std:: fs:: File ;
5
+ use std:: { collections:: BTreeMap , fs, path:: Path } ;
3
6
4
7
use crate :: KERNEL_FILE_NAME ;
5
8
6
9
pub fn create_fat_filesystem (
7
- files : BTreeMap < & str , & Path > ,
10
+ files : BTreeMap < & str , & FileDataSource > ,
8
11
out_fat_path : & Path ,
9
12
) -> anyhow:: Result < ( ) > {
10
13
const MB : u64 = 1024 * 1024 ;
11
14
12
15
// calculate needed size
13
16
let mut needed_size = 0 ;
14
- for path in files. values ( ) {
15
- let file_size = fs:: metadata ( path)
16
- . with_context ( || format ! ( "failed to read metadata of file `{}`" , path. display( ) ) ) ?
17
- . len ( ) ;
18
- needed_size += file_size;
17
+ for source in files. values ( ) {
18
+ needed_size += source. len ( ) ?;
19
19
}
20
20
21
21
// create new filesystem image file at the given path and set its length
@@ -31,7 +31,9 @@ pub fn create_fat_filesystem(
31
31
32
32
// choose a file system label
33
33
let mut label = * b"MY_RUST_OS!" ;
34
- if let Some ( path) = files. get ( KERNEL_FILE_NAME ) {
34
+
35
+ // This __should__ always be a file, but maybe not. Should we allow the caller to set the volume label instead?
36
+ if let Some ( FileDataSource :: File ( path) ) = files. get ( KERNEL_FILE_NAME ) {
35
37
if let Some ( name) = path. file_stem ( ) {
36
38
let converted = name. to_string_lossy ( ) ;
37
39
let name = converted. as_bytes ( ) ;
@@ -48,10 +50,17 @@ pub fn create_fat_filesystem(
48
50
fatfs:: format_volume ( & fat_file, format_options) . context ( "Failed to format FAT file" ) ?;
49
51
let filesystem = fatfs:: FileSystem :: new ( & fat_file, fatfs:: FsOptions :: new ( ) )
50
52
. context ( "Failed to open FAT file system of UEFI FAT file" ) ?;
53
+ let root_dir = filesystem. root_dir ( ) ;
51
54
52
55
// copy files to file system
53
- let root_dir = filesystem. root_dir ( ) ;
54
- for ( target_path_raw, file_path) in files {
56
+ add_files_to_image ( & root_dir, files)
57
+ }
58
+
59
+ pub fn add_files_to_image (
60
+ root_dir : & Dir < & File > ,
61
+ files : BTreeMap < & str , & FileDataSource > ,
62
+ ) -> anyhow:: Result < ( ) > {
63
+ for ( target_path_raw, source) in files {
55
64
let target_path = Path :: new ( target_path_raw) ;
56
65
// create parent directories
57
66
let ancestors: Vec < _ > = target_path. ancestors ( ) . skip ( 1 ) . collect ( ) ;
@@ -70,12 +79,14 @@ pub fn create_fat_filesystem(
70
79
. create_file ( target_path_raw)
71
80
. with_context ( || format ! ( "failed to create file at `{}`" , target_path. display( ) ) ) ?;
72
81
new_file. truncate ( ) . unwrap ( ) ;
73
- io:: copy (
74
- & mut fs:: File :: open ( file_path)
75
- . with_context ( || format ! ( "failed to open `{}` for copying" , file_path. display( ) ) ) ?,
76
- & mut new_file,
77
- )
78
- . with_context ( || format ! ( "failed to copy `{}` to FAT filesystem" , file_path. display( ) ) ) ?;
82
+
83
+ source. copy_to ( & mut new_file) . with_context ( || {
84
+ format ! (
85
+ "failed to copy source data `{:?}` to file at `{}`" ,
86
+ source,
87
+ target_path. display( )
88
+ )
89
+ } ) ?;
79
90
}
80
91
81
92
Ok ( ( ) )
0 commit comments