19
19
20
20
21
21
// Block device emulated on existing filesystem
22
- int lfs_emubd_create (lfs_emubd_t * emu , const char * path ) {
23
- memset (& emu -> info , 0 , sizeof (emu -> info ));
24
- memset (& emu -> stats , 0 , sizeof (emu -> stats ));
22
+ int lfs_emubd_create (const struct lfs_config * cfg , const char * path ) {
23
+ lfs_emubd_t * emu = cfg -> context ;
24
+ emu -> cfg .read_size = cfg -> read_size ;
25
+ emu -> cfg .prog_size = cfg -> prog_size ;
26
+ emu -> cfg .block_size = cfg -> block_size ;
27
+ emu -> cfg .block_count = cfg -> block_count ;
25
28
26
29
// Allocate buffer for creating children files
27
30
size_t pathlen = strlen (path );
@@ -41,12 +44,6 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
41
44
return - errno ;
42
45
}
43
46
44
- // Setup info based on configuration
45
- emu -> info .read_size = LFS_EMUBD_READ_SIZE ;
46
- emu -> info .prog_size = LFS_EMUBD_PROG_SIZE ;
47
- emu -> info .erase_size = LFS_EMUBD_ERASE_SIZE ;
48
- emu -> info .total_size = LFS_EMUBD_TOTAL_SIZE ;
49
-
50
47
// Load stats to continue incrementing
51
48
snprintf (emu -> child , LFS_NAME_MAX , "stats" );
52
49
FILE * f = fopen (emu -> path , "r" );
@@ -67,153 +64,131 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
67
64
return 0 ;
68
65
}
69
66
70
- void lfs_emubd_destroy (lfs_emubd_t * emu ) {
71
- lfs_emubd_sync (emu );
67
+ void lfs_emubd_destroy (const struct lfs_config * cfg ) {
68
+ lfs_emubd_sync (cfg );
72
69
70
+ lfs_emubd_t * emu = cfg -> context ;
73
71
free (emu -> path );
74
72
}
75
73
76
- int lfs_emubd_read (lfs_emubd_t * emu , lfs_block_t block ,
74
+ int lfs_emubd_read (const struct lfs_config * cfg , lfs_block_t block ,
77
75
lfs_off_t off , lfs_size_t size , void * buffer ) {
76
+ lfs_emubd_t * emu = cfg -> context ;
78
77
uint8_t * data = buffer ;
79
78
80
79
// Check if read is valid
81
- assert (off % emu -> info .read_size == 0 );
82
- assert (size % emu -> info .read_size == 0 );
83
- assert ((uint64_t )block * emu -> info .erase_size + off + size
84
- < emu -> info .total_size );
80
+ assert (off % cfg -> read_size == 0 );
81
+ assert (size % cfg -> read_size == 0 );
82
+ assert (block < cfg -> block_count );
85
83
86
84
// Zero out buffer for debugging
87
85
memset (data , 0 , size );
88
86
89
- // Iterate over blocks until enough data is read
90
- while (size > 0 ) {
91
- snprintf (emu -> child , LFS_NAME_MAX , "%x" , block );
92
- size_t count = lfs_min (emu -> info .erase_size - off , size );
87
+ // Read data
88
+ snprintf (emu -> child , LFS_NAME_MAX , "%x" , block );
89
+
90
+ FILE * f = fopen (emu -> path , "rb" );
91
+ if (!f && errno != ENOENT ) {
92
+ return - errno ;
93
+ }
93
94
94
- FILE * f = fopen (emu -> path , "rb" );
95
- if (!f && errno != ENOENT ) {
95
+ if (f ) {
96
+ int err = fseek (f , off , SEEK_SET );
97
+ if (err ) {
96
98
return - errno ;
97
99
}
98
100
99
- if (f ) {
100
- int err = fseek (f , off , SEEK_SET );
101
- if (err ) {
102
- return - errno ;
103
- }
104
-
105
- size_t res = fread (data , 1 , count , f );
106
- if (res < count && !feof (f )) {
107
- return - errno ;
108
- }
109
-
110
- err = fclose (f );
111
- if (err ) {
112
- return - errno ;
113
- }
101
+ size_t res = fread (data , 1 , size , f );
102
+ if (res < size && !feof (f )) {
103
+ return - errno ;
114
104
}
115
105
116
- size -= count ;
117
- data += count ;
118
- block += 1 ;
119
- off = 0 ;
106
+ err = fclose ( f ) ;
107
+ if ( err ) {
108
+ return - errno ;
109
+ }
120
110
}
121
111
122
112
emu -> stats .read_count += 1 ;
123
113
return 0 ;
124
114
}
125
115
126
- int lfs_emubd_prog (lfs_emubd_t * emu , lfs_block_t block ,
116
+ int lfs_emubd_prog (const struct lfs_config * cfg , lfs_block_t block ,
127
117
lfs_off_t off , lfs_size_t size , const void * buffer ) {
118
+ lfs_emubd_t * emu = cfg -> context ;
128
119
const uint8_t * data = buffer ;
129
120
130
121
// Check if write is valid
131
- assert (off % emu -> info .prog_size == 0 );
132
- assert (size % emu -> info .prog_size == 0 );
133
- assert ((uint64_t )block * emu -> info .erase_size + off + size
134
- < emu -> info .total_size );
135
-
136
- // Iterate over blocks until enough data is read
137
- while (size > 0 ) {
138
- snprintf (emu -> child , LFS_NAME_MAX , "%x" , block );
139
- size_t count = lfs_min (emu -> info .erase_size - off , size );
140
-
141
- FILE * f = fopen (emu -> path , "r+b" );
142
- if (!f && errno == ENOENT ) {
143
- f = fopen (emu -> path , "w+b" );
144
- if (!f ) {
145
- return - errno ;
146
- }
147
- }
122
+ assert (off % cfg -> prog_size == 0 );
123
+ assert (size % cfg -> prog_size == 0 );
124
+ assert (block < cfg -> block_count );
148
125
149
- int err = fseek (f , off , SEEK_SET );
150
- if (err ) {
151
- return - errno ;
152
- }
126
+ // Program data
127
+ snprintf (emu -> child , LFS_NAME_MAX , "%x" , block );
153
128
154
- size_t res = fwrite (data , 1 , count , f );
155
- if (res < count ) {
129
+ FILE * f = fopen (emu -> path , "r+b" );
130
+ if (!f && errno == ENOENT ) {
131
+ f = fopen (emu -> path , "w+b" );
132
+ if (!f ) {
156
133
return - errno ;
157
134
}
135
+ }
158
136
159
- err = fclose (f );
160
- if (err ) {
161
- return - errno ;
162
- }
137
+ int err = fseek (f , off , SEEK_SET );
138
+ if (err ) {
139
+ return - errno ;
140
+ }
141
+
142
+ size_t res = fwrite (data , 1 , size , f );
143
+ if (res < size ) {
144
+ return - errno ;
145
+ }
163
146
164
- size -= count ;
165
- data += count ;
166
- block += 1 ;
167
- off = 0 ;
147
+ err = fclose (f );
148
+ if (err ) {
149
+ return - errno ;
168
150
}
169
151
170
152
emu -> stats .prog_count += 1 ;
171
153
return 0 ;
172
154
}
173
155
174
- int lfs_emubd_erase (lfs_emubd_t * emu , lfs_block_t block ,
175
- lfs_off_t off , lfs_size_t size ) {
156
+ int lfs_emubd_erase (const struct lfs_config * cfg , lfs_block_t block ) {
157
+ lfs_emubd_t * emu = cfg -> context ;
176
158
177
159
// Check if erase is valid
178
- assert (off % emu -> info .erase_size == 0 );
179
- assert (size % emu -> info .erase_size == 0 );
180
- assert ((uint64_t )block * emu -> info .erase_size + off + size
181
- < emu -> info .total_size );
182
-
183
- // Iterate and erase blocks
184
- while (size > 0 ) {
185
- snprintf (emu -> child , LFS_NAME_MAX , "%x" , block );
186
- struct stat st ;
187
- int err = stat (emu -> path , & st );
188
- if (err && errno != ENOENT ) {
189
- return - errno ;
190
- }
160
+ assert (block < cfg -> block_count );
191
161
192
- if (!err && S_ISREG (st .st_mode )) {
193
- int err = unlink (emu -> path );
194
- if (err ) {
195
- return - errno ;
196
- }
197
- }
162
+ // Erase the block
163
+ snprintf (emu -> child , LFS_NAME_MAX , "%x" , block );
164
+ struct stat st ;
165
+ int err = stat (emu -> path , & st );
166
+ if (err && errno != ENOENT ) {
167
+ return - errno ;
168
+ }
198
169
199
- size -= emu -> info .erase_size ;
200
- block += 1 ;
201
- off = 0 ;
170
+ if (!err && S_ISREG (st .st_mode )) {
171
+ int err = unlink (emu -> path );
172
+ if (err ) {
173
+ return - errno ;
174
+ }
202
175
}
203
176
204
177
emu -> stats .erase_count += 1 ;
205
178
return 0 ;
206
179
}
207
180
208
- int lfs_emubd_sync (lfs_emubd_t * emu ) {
181
+ int lfs_emubd_sync (const struct lfs_config * cfg ) {
182
+ lfs_emubd_t * emu = cfg -> context ;
183
+
209
184
// Just write out info/stats for later lookup
210
- snprintf (emu -> child , LFS_NAME_MAX , "info " );
185
+ snprintf (emu -> child , LFS_NAME_MAX , "config " );
211
186
FILE * f = fopen (emu -> path , "w" );
212
187
if (!f ) {
213
188
return - errno ;
214
189
}
215
190
216
- size_t res = fwrite (& emu -> info , sizeof (emu -> info ), 1 , f );
191
+ size_t res = fwrite (& emu -> cfg , sizeof (emu -> cfg ), 1 , f );
217
192
if (res < 1 ) {
218
193
return - errno ;
219
194
}
@@ -242,46 +217,3 @@ int lfs_emubd_sync(lfs_emubd_t *emu) {
242
217
return 0 ;
243
218
}
244
219
245
- int lfs_emubd_info (lfs_emubd_t * emu , struct lfs_bd_info * info ) {
246
- * info = emu -> info ;
247
- return 0 ;
248
- }
249
-
250
- int lfs_emubd_stats (lfs_emubd_t * emu , struct lfs_bd_stats * stats ) {
251
- * stats = emu -> stats ;
252
- return 0 ;
253
- }
254
-
255
-
256
- // Wrappers for void*s
257
- static int lfs_emubd_bd_read (void * bd , lfs_block_t block ,
258
- lfs_off_t off , lfs_size_t size , void * buffer ) {
259
- return lfs_emubd_read ((lfs_emubd_t * )bd , block , off , size , buffer );
260
- }
261
-
262
- static int lfs_emubd_bd_prog (void * bd , lfs_block_t block ,
263
- lfs_off_t off , lfs_size_t size , const void * buffer ) {
264
- return lfs_emubd_prog ((lfs_emubd_t * )bd , block , off , size , buffer );
265
- }
266
-
267
- static int lfs_emubd_bd_erase (void * bd , lfs_block_t block ,
268
- lfs_off_t off , lfs_size_t size ) {
269
- return lfs_emubd_erase ((lfs_emubd_t * )bd , block , off , size );
270
- }
271
-
272
- static int lfs_emubd_bd_sync (void * bd ) {
273
- return lfs_emubd_sync ((lfs_emubd_t * )bd );
274
- }
275
-
276
- static int lfs_emubd_bd_info (void * bd , struct lfs_bd_info * info ) {
277
- return lfs_emubd_info ((lfs_emubd_t * )bd , info );
278
- }
279
-
280
- const struct lfs_bd_ops lfs_emubd_ops = {
281
- .read = lfs_emubd_bd_read ,
282
- .prog = lfs_emubd_bd_prog ,
283
- .erase = lfs_emubd_bd_erase ,
284
- .sync = lfs_emubd_bd_sync ,
285
- .info = lfs_emubd_bd_info ,
286
- };
287
-
0 commit comments