1919
2020
2121// 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 ;
2528
2629 // Allocate buffer for creating children files
2730 size_t pathlen = strlen (path );
@@ -41,12 +44,6 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
4144 return - errno ;
4245 }
4346
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-
5047 // Load stats to continue incrementing
5148 snprintf (emu -> child , LFS_NAME_MAX , "stats" );
5249 FILE * f = fopen (emu -> path , "r" );
@@ -67,153 +64,131 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
6764 return 0 ;
6865}
6966
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 );
7269
70+ lfs_emubd_t * emu = cfg -> context ;
7371 free (emu -> path );
7472}
7573
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 ,
7775 lfs_off_t off , lfs_size_t size , void * buffer ) {
76+ lfs_emubd_t * emu = cfg -> context ;
7877 uint8_t * data = buffer ;
7978
8079 // 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 );
8583
8684 // Zero out buffer for debugging
8785 memset (data , 0 , size );
8886
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+ }
9394
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 ) {
9698 return - errno ;
9799 }
98100
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 ;
114104 }
115105
116- size -= count ;
117- data += count ;
118- block += 1 ;
119- off = 0 ;
106+ err = fclose ( f ) ;
107+ if ( err ) {
108+ return - errno ;
109+ }
120110 }
121111
122112 emu -> stats .read_count += 1 ;
123113 return 0 ;
124114}
125115
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 ,
127117 lfs_off_t off , lfs_size_t size , const void * buffer ) {
118+ lfs_emubd_t * emu = cfg -> context ;
128119 const uint8_t * data = buffer ;
129120
130121 // 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 );
148125
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 );
153128
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 ) {
156133 return - errno ;
157134 }
135+ }
158136
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+ }
163146
164- size -= count ;
165- data += count ;
166- block += 1 ;
167- off = 0 ;
147+ err = fclose (f );
148+ if (err ) {
149+ return - errno ;
168150 }
169151
170152 emu -> stats .prog_count += 1 ;
171153 return 0 ;
172154}
173155
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 ;
176158
177159 // 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 );
191161
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+ }
198169
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+ }
202175 }
203176
204177 emu -> stats .erase_count += 1 ;
205178 return 0 ;
206179}
207180
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+
209184 // Just write out info/stats for later lookup
210- snprintf (emu -> child , LFS_NAME_MAX , "info " );
185+ snprintf (emu -> child , LFS_NAME_MAX , "config " );
211186 FILE * f = fopen (emu -> path , "w" );
212187 if (!f ) {
213188 return - errno ;
214189 }
215190
216- size_t res = fwrite (& emu -> info , sizeof (emu -> info ), 1 , f );
191+ size_t res = fwrite (& emu -> cfg , sizeof (emu -> cfg ), 1 , f );
217192 if (res < 1 ) {
218193 return - errno ;
219194 }
@@ -242,46 +217,3 @@ int lfs_emubd_sync(lfs_emubd_t *emu) {
242217 return 0 ;
243218}
244219
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