Lines Matching +full:- +full:- +full:disk
7 * SPDX-License-Identifier: BSD-3-Clause
27 // access to lazily-allocated/copy-on-write blocks
34 block->rc += 1; in lfs_emubd_incblock()
41 block->rc -= 1; in lfs_emubd_decblock()
42 if (block->rc == 0) { in lfs_emubd_decblock()
51 lfs_emubd_t *bd = cfg->context; in lfs_emubd_mutblock()
53 if (block_ && block_->rc == 1) { in lfs_emubd_mutblock()
60 sizeof(lfs_emubd_block_t) + bd->cfg->erase_size); in lfs_emubd_mutblock()
66 sizeof(lfs_emubd_block_t) + bd->cfg->erase_size); in lfs_emubd_mutblock()
67 nblock->rc = 1; in lfs_emubd_mutblock()
76 sizeof(lfs_emubd_block_t) + bd->cfg->erase_size); in lfs_emubd_mutblock()
81 nblock->rc = 1; in lfs_emubd_mutblock()
82 nblock->wear = 0; in lfs_emubd_mutblock()
85 memset(nblock->data, in lfs_emubd_mutblock()
86 (bd->cfg->erase_value != -1) ? bd->cfg->erase_value : 0, in lfs_emubd_mutblock()
87 bd->cfg->erase_size); in lfs_emubd_mutblock()
107 (void*)cfg, cfg->context, in lfs_emubd_create()
108 (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, in lfs_emubd_create()
109 (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, in lfs_emubd_create()
111 bdcfg->read_size, bdcfg->prog_size, bdcfg->erase_size, in lfs_emubd_create()
112 bdcfg->erase_count, bdcfg->erase_value, bdcfg->erase_cycles, in lfs_emubd_create()
113 bdcfg->badblock_behavior, bdcfg->power_cycles, in lfs_emubd_create()
114 bdcfg->powerloss_behavior, (void*)(uintptr_t)bdcfg->powerloss_cb, in lfs_emubd_create()
115 bdcfg->powerloss_data, bdcfg->track_branches); in lfs_emubd_create()
116 lfs_emubd_t *bd = cfg->context; in lfs_emubd_create()
117 bd->cfg = bdcfg; in lfs_emubd_create()
120 bd->blocks = malloc(bd->cfg->erase_count * sizeof(lfs_emubd_block_t*)); in lfs_emubd_create()
121 if (!bd->blocks) { in lfs_emubd_create()
122 LFS_EMUBD_TRACE("lfs_emubd_create -> %d", LFS_ERR_NOMEM); in lfs_emubd_create()
125 memset(bd->blocks, 0, bd->cfg->erase_count * sizeof(lfs_emubd_block_t*)); in lfs_emubd_create()
128 bd->readed = 0; in lfs_emubd_create()
129 bd->proged = 0; in lfs_emubd_create()
130 bd->erased = 0; in lfs_emubd_create()
131 bd->power_cycles = bd->cfg->power_cycles; in lfs_emubd_create()
132 bd->disk = NULL; in lfs_emubd_create()
134 if (bd->cfg->disk_path) { in lfs_emubd_create()
135 bd->disk = malloc(sizeof(lfs_emubd_disk_t)); in lfs_emubd_create()
136 if (!bd->disk) { in lfs_emubd_create()
137 LFS_EMUBD_TRACE("lfs_emubd_create -> %d", LFS_ERR_NOMEM); in lfs_emubd_create()
140 bd->disk->rc = 1; in lfs_emubd_create()
141 bd->disk->scratch = NULL; in lfs_emubd_create()
144 bd->disk->fd = open(bd->cfg->disk_path, in lfs_emubd_create()
147 bd->disk->fd = open(bd->cfg->disk_path, in lfs_emubd_create()
150 if (bd->disk->fd < 0) { in lfs_emubd_create()
151 int err = -errno; in lfs_emubd_create()
152 LFS_EMUBD_TRACE("lfs_emubd_create -> %d", err); in lfs_emubd_create()
158 if (bd->cfg->erase_value != -1) { in lfs_emubd_create()
159 bd->disk->scratch = malloc(bd->cfg->erase_size); in lfs_emubd_create()
160 if (!bd->disk->scratch) { in lfs_emubd_create()
161 LFS_EMUBD_TRACE("lfs_emubd_create -> %d", LFS_ERR_NOMEM); in lfs_emubd_create()
164 memset(bd->disk->scratch, in lfs_emubd_create()
165 bd->cfg->erase_value, in lfs_emubd_create()
166 bd->cfg->erase_size); in lfs_emubd_create()
168 // go ahead and erase all of the disk, otherwise the file will not in lfs_emubd_create()
170 for (size_t i = 0; i < bd->cfg->erase_count; i++) { in lfs_emubd_create()
171 ssize_t res = write(bd->disk->fd, in lfs_emubd_create()
172 bd->disk->scratch, in lfs_emubd_create()
173 bd->cfg->erase_size); in lfs_emubd_create()
175 int err = -errno; in lfs_emubd_create()
176 LFS_EMUBD_TRACE("lfs_emubd_create -> %d", err); in lfs_emubd_create()
183 LFS_EMUBD_TRACE("lfs_emubd_create -> %d", 0); in lfs_emubd_create()
189 lfs_emubd_t *bd = cfg->context; in lfs_emubd_destroy()
192 for (lfs_block_t i = 0; i < bd->cfg->erase_count; i++) { in lfs_emubd_destroy()
193 lfs_emubd_decblock(bd->blocks[i]); in lfs_emubd_destroy()
195 free(bd->blocks); in lfs_emubd_destroy()
198 if (bd->disk) { in lfs_emubd_destroy()
199 bd->disk->rc -= 1; in lfs_emubd_destroy()
200 if (bd->disk->rc == 0) { in lfs_emubd_destroy()
201 close(bd->disk->fd); in lfs_emubd_destroy()
202 free(bd->disk->scratch); in lfs_emubd_destroy()
203 free(bd->disk); in lfs_emubd_destroy()
207 LFS_EMUBD_TRACE("lfs_emubd_destroy -> %d", 0); in lfs_emubd_destroy()
220 lfs_emubd_t *bd = cfg->context; in lfs_emubd_read()
223 LFS_ASSERT(block < bd->cfg->erase_count); in lfs_emubd_read()
224 LFS_ASSERT(off % bd->cfg->read_size == 0); in lfs_emubd_read()
225 LFS_ASSERT(size % bd->cfg->read_size == 0); in lfs_emubd_read()
226 LFS_ASSERT(off+size <= bd->cfg->erase_size); in lfs_emubd_read()
229 const lfs_emubd_block_t *b = bd->blocks[block]; in lfs_emubd_read()
232 if (bd->cfg->erase_cycles && b->wear >= bd->cfg->erase_cycles && in lfs_emubd_read()
233 bd->cfg->badblock_behavior == LFS_EMUBD_BADBLOCK_READERROR) { in lfs_emubd_read()
234 LFS_EMUBD_TRACE("lfs_emubd_read -> %d", LFS_ERR_CORRUPT); in lfs_emubd_read()
239 memcpy(buffer, &b->data[off], size); in lfs_emubd_read()
243 (bd->cfg->erase_value != -1) ? bd->cfg->erase_value : 0, in lfs_emubd_read()
248 bd->readed += size; in lfs_emubd_read()
249 if (bd->cfg->read_sleep) { in lfs_emubd_read()
251 .tv_sec=bd->cfg->read_sleep/1000000000, in lfs_emubd_read()
252 .tv_nsec=bd->cfg->read_sleep%1000000000}, in lfs_emubd_read()
255 err = -errno; in lfs_emubd_read()
256 LFS_EMUBD_TRACE("lfs_emubd_read -> %d", err); in lfs_emubd_read()
261 LFS_EMUBD_TRACE("lfs_emubd_read -> %d", 0); in lfs_emubd_read()
270 lfs_emubd_t *bd = cfg->context; in lfs_emubd_prog()
273 LFS_ASSERT(block < bd->cfg->erase_count); in lfs_emubd_prog()
274 LFS_ASSERT(off % bd->cfg->prog_size == 0); in lfs_emubd_prog()
275 LFS_ASSERT(size % bd->cfg->prog_size == 0); in lfs_emubd_prog()
276 LFS_ASSERT(off+size <= bd->cfg->erase_size); in lfs_emubd_prog()
279 lfs_emubd_block_t *b = lfs_emubd_mutblock(cfg, &bd->blocks[block]); in lfs_emubd_prog()
281 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", LFS_ERR_NOMEM); in lfs_emubd_prog()
286 if (bd->cfg->erase_cycles && b->wear >= bd->cfg->erase_cycles) { in lfs_emubd_prog()
287 if (bd->cfg->badblock_behavior == in lfs_emubd_prog()
289 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", LFS_ERR_CORRUPT); in lfs_emubd_prog()
291 } else if (bd->cfg->badblock_behavior == in lfs_emubd_prog()
293 bd->cfg->badblock_behavior == in lfs_emubd_prog()
295 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", 0); in lfs_emubd_prog()
301 if (bd->cfg->erase_value != -1) { in lfs_emubd_prog()
303 LFS_ASSERT(b->data[off+i] == bd->cfg->erase_value); in lfs_emubd_prog()
308 memcpy(&b->data[off], buffer, size); in lfs_emubd_prog()
310 // mirror to disk file? in lfs_emubd_prog()
311 if (bd->disk) { in lfs_emubd_prog()
312 off_t res1 = lseek(bd->disk->fd, in lfs_emubd_prog()
313 (off_t)block*bd->cfg->erase_size + (off_t)off, in lfs_emubd_prog()
316 int err = -errno; in lfs_emubd_prog()
317 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", err); in lfs_emubd_prog()
321 ssize_t res2 = write(bd->disk->fd, buffer, size); in lfs_emubd_prog()
323 int err = -errno; in lfs_emubd_prog()
324 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", err); in lfs_emubd_prog()
330 bd->proged += size; in lfs_emubd_prog()
331 if (bd->cfg->prog_sleep) { in lfs_emubd_prog()
333 .tv_sec=bd->cfg->prog_sleep/1000000000, in lfs_emubd_prog()
334 .tv_nsec=bd->cfg->prog_sleep%1000000000}, in lfs_emubd_prog()
337 err = -errno; in lfs_emubd_prog()
338 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", err); in lfs_emubd_prog()
344 if (bd->power_cycles > 0) { in lfs_emubd_prog()
345 bd->power_cycles -= 1; in lfs_emubd_prog()
346 if (bd->power_cycles == 0) { in lfs_emubd_prog()
348 bd->cfg->powerloss_cb(bd->cfg->powerloss_data); in lfs_emubd_prog()
352 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", 0); in lfs_emubd_prog()
358 (void*)cfg, block, ((lfs_emubd_t*)cfg->context)->cfg->erase_size); in lfs_emubd_erase()
359 lfs_emubd_t *bd = cfg->context; in lfs_emubd_erase()
362 LFS_ASSERT(block < bd->cfg->erase_count); in lfs_emubd_erase()
365 lfs_emubd_block_t *b = lfs_emubd_mutblock(cfg, &bd->blocks[block]); in lfs_emubd_erase()
367 LFS_EMUBD_TRACE("lfs_emubd_prog -> %d", LFS_ERR_NOMEM); in lfs_emubd_erase()
372 if (bd->cfg->erase_cycles) { in lfs_emubd_erase()
373 if (b->wear >= bd->cfg->erase_cycles) { in lfs_emubd_erase()
374 if (bd->cfg->badblock_behavior == in lfs_emubd_erase()
376 LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", LFS_ERR_CORRUPT); in lfs_emubd_erase()
378 } else if (bd->cfg->badblock_behavior == in lfs_emubd_erase()
380 LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", 0); in lfs_emubd_erase()
385 b->wear += 1; in lfs_emubd_erase()
390 if (bd->cfg->erase_value != -1) { in lfs_emubd_erase()
391 memset(b->data, bd->cfg->erase_value, bd->cfg->erase_size); in lfs_emubd_erase()
393 // mirror to disk file? in lfs_emubd_erase()
394 if (bd->disk) { in lfs_emubd_erase()
395 off_t res1 = lseek(bd->disk->fd, in lfs_emubd_erase()
396 (off_t)block*bd->cfg->erase_size, in lfs_emubd_erase()
399 int err = -errno; in lfs_emubd_erase()
400 LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", err); in lfs_emubd_erase()
404 ssize_t res2 = write(bd->disk->fd, in lfs_emubd_erase()
405 bd->disk->scratch, in lfs_emubd_erase()
406 bd->cfg->erase_size); in lfs_emubd_erase()
408 int err = -errno; in lfs_emubd_erase()
409 LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", err); in lfs_emubd_erase()
416 bd->erased += bd->cfg->erase_size; in lfs_emubd_erase()
417 if (bd->cfg->erase_sleep) { in lfs_emubd_erase()
419 .tv_sec=bd->cfg->erase_sleep/1000000000, in lfs_emubd_erase()
420 .tv_nsec=bd->cfg->erase_sleep%1000000000}, in lfs_emubd_erase()
423 err = -errno; in lfs_emubd_erase()
424 LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", err); in lfs_emubd_erase()
430 if (bd->power_cycles > 0) { in lfs_emubd_erase()
431 bd->power_cycles -= 1; in lfs_emubd_erase()
432 if (bd->power_cycles == 0) { in lfs_emubd_erase()
434 bd->cfg->powerloss_cb(bd->cfg->powerloss_data); in lfs_emubd_erase()
438 LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", 0); in lfs_emubd_erase()
448 LFS_EMUBD_TRACE("lfs_emubd_sync -> %d", 0); in lfs_emubd_sync()
456 lfs_emubd_t *bd = cfg->context; in lfs_emubd_rawcrc()
459 LFS_ASSERT(block < cfg->block_count); in lfs_emubd_rawcrc()
463 const lfs_emubd_block_t *b = bd->blocks[block]; in lfs_emubd_rawcrc()
465 crc_ = lfs_crc(crc_, b->data, cfg->block_size); in lfs_emubd_rawcrc()
467 uint8_t erase_value = (bd->cfg->erase_value != -1) in lfs_emubd_rawcrc()
468 ? bd->cfg->erase_value in lfs_emubd_rawcrc()
470 for (lfs_size_t i = 0; i < cfg->block_size; i++) { in lfs_emubd_rawcrc()
484 LFS_EMUBD_TRACE("lfs_emubd_crc -> %d", err); in lfs_emubd_crc()
492 for (lfs_block_t i = 0; i < cfg->block_count; i++) { in lfs_emubd_bdcrc()
496 LFS_EMUBD_TRACE("lfs_emubd_bdcrc -> %d", err); in lfs_emubd_bdcrc()
504 LFS_EMUBD_TRACE("lfs_emubd_bdcrc -> %d", 0); in lfs_emubd_bdcrc()
510 lfs_emubd_t *bd = cfg->context; in lfs_emubd_readed()
511 LFS_EMUBD_TRACE("lfs_emubd_readed -> %"PRIu64, bd->readed); in lfs_emubd_readed()
512 return bd->readed; in lfs_emubd_readed()
517 lfs_emubd_t *bd = cfg->context; in lfs_emubd_proged()
518 LFS_EMUBD_TRACE("lfs_emubd_proged -> %"PRIu64, bd->proged); in lfs_emubd_proged()
519 return bd->proged; in lfs_emubd_proged()
524 lfs_emubd_t *bd = cfg->context; in lfs_emubd_erased()
525 LFS_EMUBD_TRACE("lfs_emubd_erased -> %"PRIu64, bd->erased); in lfs_emubd_erased()
526 return bd->erased; in lfs_emubd_erased()
531 lfs_emubd_t *bd = cfg->context; in lfs_emubd_setreaded()
532 bd->readed = readed; in lfs_emubd_setreaded()
533 LFS_EMUBD_TRACE("lfs_emubd_setreaded -> %d", 0); in lfs_emubd_setreaded()
539 lfs_emubd_t *bd = cfg->context; in lfs_emubd_setproged()
540 bd->proged = proged; in lfs_emubd_setproged()
541 LFS_EMUBD_TRACE("lfs_emubd_setproged -> %d", 0); in lfs_emubd_setproged()
547 lfs_emubd_t *bd = cfg->context; in lfs_emubd_seterased()
548 bd->erased = erased; in lfs_emubd_seterased()
549 LFS_EMUBD_TRACE("lfs_emubd_seterased -> %d", 0); in lfs_emubd_seterased()
556 lfs_emubd_t *bd = cfg->context; in lfs_emubd_wear()
559 LFS_ASSERT(block < bd->cfg->erase_count); in lfs_emubd_wear()
563 const lfs_emubd_block_t *b = bd->blocks[block]; in lfs_emubd_wear()
565 wear = b->wear; in lfs_emubd_wear()
570 LFS_EMUBD_TRACE("lfs_emubd_wear -> %"PRIi32, wear); in lfs_emubd_wear()
578 lfs_emubd_t *bd = cfg->context; in lfs_emubd_setwear()
581 LFS_ASSERT(block < bd->cfg->erase_count); in lfs_emubd_setwear()
584 lfs_emubd_block_t *b = lfs_emubd_mutblock(cfg, &bd->blocks[block]); in lfs_emubd_setwear()
586 LFS_EMUBD_TRACE("lfs_emubd_setwear -> %d", LFS_ERR_NOMEM); in lfs_emubd_setwear()
589 b->wear = wear; in lfs_emubd_setwear()
591 LFS_EMUBD_TRACE("lfs_emubd_setwear -> %d", 0); in lfs_emubd_setwear()
598 lfs_emubd_t *bd = cfg->context; in lfs_emubd_powercycles()
600 LFS_EMUBD_TRACE("lfs_emubd_powercycles -> %"PRIi32, bd->power_cycles); in lfs_emubd_powercycles()
601 return bd->power_cycles; in lfs_emubd_powercycles()
608 lfs_emubd_t *bd = cfg->context; in lfs_emubd_setpowercycles()
610 bd->power_cycles = power_cycles; in lfs_emubd_setpowercycles()
612 LFS_EMUBD_TRACE("lfs_emubd_powercycles -> %d", 0); in lfs_emubd_setpowercycles()
618 lfs_emubd_t *bd = cfg->context; in lfs_emubd_copy()
621 copy->blocks = malloc(bd->cfg->erase_count * sizeof(lfs_emubd_block_t*)); in lfs_emubd_copy()
622 if (!copy->blocks) { in lfs_emubd_copy()
623 LFS_EMUBD_TRACE("lfs_emubd_copy -> %d", LFS_ERR_NOMEM); in lfs_emubd_copy()
627 for (size_t i = 0; i < bd->cfg->erase_count; i++) { in lfs_emubd_copy()
628 copy->blocks[i] = lfs_emubd_incblock(bd->blocks[i]); in lfs_emubd_copy()
632 copy->readed = bd->readed; in lfs_emubd_copy()
633 copy->proged = bd->proged; in lfs_emubd_copy()
634 copy->erased = bd->erased; in lfs_emubd_copy()
635 copy->power_cycles = bd->power_cycles; in lfs_emubd_copy()
636 copy->disk = bd->disk; in lfs_emubd_copy()
637 if (copy->disk) { in lfs_emubd_copy()
638 copy->disk->rc += 1; in lfs_emubd_copy()
640 copy->cfg = bd->cfg; in lfs_emubd_copy()
642 LFS_EMUBD_TRACE("lfs_emubd_copy -> %d", 0); in lfs_emubd_copy()