123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- /*
- * Copyright (c) 2017 Nordic Semiconductor ASA
- * Copyright (c) 2015 Runtime Inc
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <stddef.h>
- #include <fs/fcb.h>
- #include "fcb_priv.h"
- int
- fcb_getnext_in_sector(struct fcb *fcb, struct fcb_entry *loc)
- {
- int rc;
- rc = fcb_elem_info(fcb, loc);
- if (rc == 0 || rc == -EBADMSG) {
- do {
- loc->fe_elem_off = loc->fe_data_off +
- fcb_len_in_flash(fcb, loc->fe_data_len) +
- fcb_len_in_flash(fcb, FCB_CRC_SZ);
- rc = fcb_elem_info(fcb, loc);
- if (rc != -EBADMSG) {
- break;
- }
- } while (rc == -EBADMSG);
- }
- return rc;
- }
- struct flash_sector *
- fcb_getnext_sector(struct fcb *fcb, struct flash_sector *sector)
- {
- sector++;
- if (sector >= &fcb->f_sectors[fcb->f_sector_cnt]) {
- sector = &fcb->f_sectors[0];
- }
- return sector;
- }
- int
- fcb_getnext_nolock(struct fcb *fcb, struct fcb_entry *loc)
- {
- int rc;
- if (loc->fe_sector == NULL) {
- /*
- * Find the first one we have in flash.
- */
- loc->fe_sector = fcb->f_oldest;
- }
- if (loc->fe_elem_off == 0U) {
- /*
- * If offset is zero, we serve the first entry from the sector.
- */
- loc->fe_elem_off = sizeof(struct fcb_disk_area);
- rc = fcb_elem_info(fcb, loc);
- switch (rc) {
- case 0:
- return 0;
- case -EBADMSG:
- break;
- default:
- goto next_sector;
- }
- } else {
- rc = fcb_getnext_in_sector(fcb, loc);
- if (rc == 0) {
- return 0;
- }
- if (rc == -ENOTSUP) {
- goto next_sector;
- }
- }
- while (rc == -EBADMSG) {
- rc = fcb_getnext_in_sector(fcb, loc);
- if (rc == 0) {
- return 0;
- }
- if (rc != -EBADMSG) {
- /*
- * Moving to next sector.
- */
- next_sector:
- if (loc->fe_sector == fcb->f_active.fe_sector) {
- return -ENOTSUP;
- }
- loc->fe_sector = fcb_getnext_sector(fcb, loc->fe_sector);
- loc->fe_elem_off = sizeof(struct fcb_disk_area);
- rc = fcb_elem_info(fcb, loc);
- switch (rc) {
- case 0:
- return 0;
- case -EBADMSG:
- break;
- default:
- goto next_sector;
- }
- }
- }
- return 0;
- }
- int
- fcb_getnext(struct fcb *fcb, struct fcb_entry *loc)
- {
- int rc;
- rc = k_mutex_lock(&fcb->f_mtx, K_FOREVER);
- if (rc) {
- return -EINVAL;
- }
- rc = fcb_getnext_nolock(fcb, loc);
- k_mutex_unlock(&fcb->f_mtx);
- return rc;
- }
|