Skip to content

Commit 9732e4e

Browse files
rghaddabeivindj-nordic
authored andcommitted
bm_zms: fix a bug in case of read after a write
When a read is triggered immediately after a write it can start just after a sector is closed and picks up the wrong address to start the search from. Fix this by storing a backup read address before closing a sector. Signed-off-by: Riadh Ghaddab <riadh.ghaddab@nordicsemi.no>
1 parent 8d217db commit 9732e4e

2 files changed

Lines changed: 25 additions & 5 deletions

File tree

include/bm/fs/bm_zms.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ struct bm_zms_fs {
9090
* - low 4 bytes are the offset in the sector.
9191
*/
9292
uint64_t ate_wra;
93+
/** Allocation Table Entry (ATE) read address. */
94+
uint64_t ate_ra;
9395
/** Data write address */
9496
uint64_t data_wra;
9597
/** Storage system is split into sectors. The sector size must be a multiple of

subsys/fs/bm_zms/bm_zms.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,12 @@ static int zms_compute_prev_addr(struct bm_zms_fs *fs, uint64_t *addr)
11401140
struct zms_ate empty_ate;
11411141
struct zms_ate close_ate;
11421142

1143+
if (SECTOR_OFFSET(*addr) >= (fs->sector_size - 2 * fs->ate_size)) {
1144+
LOG_ERR("Something went wrong in computing previous ate address, addr is 0x%llx",
1145+
*addr);
1146+
return -EIO;
1147+
}
1148+
11431149
*addr += fs->ate_size;
11441150
if ((SECTOR_OFFSET(*addr)) != (fs->sector_size - 2 * fs->ate_size)) {
11451151
return 0;
@@ -1230,6 +1236,7 @@ static int zms_sector_close(struct bm_zms_fs *fs)
12301236
cur_op.ate_entry.metadata = 0xffffffff;
12311237
cur_op.ate_entry.cycle_cnt = fs->sector_cycle;
12321238
zms_ate_crc8_update(&cur_op.ate_entry);
1239+
fs->ate_ra = fs->ate_wra;
12331240
fs->ate_wra = zms_close_ate_addr(fs, fs->ate_wra);
12341241
cur_op.addr = fs->ate_wra;
12351242
cur_op.len = sizeof(struct zms_ate);
@@ -2214,6 +2221,7 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
22142221
uint64_t wlk_addr;
22152222
uint64_t rd_addr = 0;
22162223
uint64_t wlk_prev_addr = 0;
2224+
uint64_t end_search_addr = 0;
22172225
uint32_t cnt_his;
22182226
struct zms_ate wlk_ate;
22192227
#ifdef CONFIG_BM_ZMS_DATA_CRC
@@ -2242,13 +2250,21 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
22422250
wlk_addr = fs->ate_wra;
22432251
#endif
22442252

2253+
end_search_addr = fs->ate_wra;
2254+
if (SECTOR_OFFSET(wlk_addr) >= (fs->sector_size - 2 * fs->ate_size)) {
2255+
/* we are maybe in the middle of a GC */
2256+
wlk_addr = fs->ate_ra;
2257+
end_search_addr = wlk_addr;
2258+
}
2259+
22452260
while (cnt_his <= cnt) {
22462261
wlk_prev_addr = wlk_addr;
22472262
/* Search for a previous valid ATE with the same ID */
2248-
prev_found = zms_find_ate_with_id(fs, id, wlk_addr, fs->ate_wra, &wlk_ate,
2263+
prev_found = zms_find_ate_with_id(fs, id, wlk_addr, end_search_addr, &wlk_ate,
22492264
&wlk_prev_addr);
22502265
if (prev_found < 0) {
2251-
return prev_found;
2266+
rc = prev_found;
2267+
goto err;
22522268
}
22532269
if (prev_found) {
22542270
cnt_his++;
@@ -2260,7 +2276,7 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
22602276
*/
22612277
rc = zms_compute_prev_addr(fs, &wlk_prev_addr);
22622278
if (rc) {
2263-
return rc;
2279+
goto err;
22642280
}
22652281
/* wlk_addr will be the start research address in the next loop */
22662282
wlk_addr = wlk_prev_addr;
@@ -2270,7 +2286,8 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
22702286
}
22712287

22722288
if (((!prev_found) || (wlk_ate.id != id)) || (wlk_ate.len == 0U) || (cnt_his < cnt)) {
2273-
return -ENOENT;
2289+
rc = -ENOENT;
2290+
goto err;
22742291
}
22752292

22762293
if (wlk_ate.len <= ZMS_DATA_IN_ATE_SIZE) {
@@ -2296,7 +2313,8 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
22962313
LOG_ERR("Invalid data CRC, ATE_CRC: 0x%08X, "
22972314
"computed_data_crc: 0x%08X",
22982315
wlk_ate.data_crc, computed_data_crc);
2299-
return -EIO;
2316+
rc = -EIO;
2317+
goto err;
23002318
}
23012319
}
23022320
#endif

0 commit comments

Comments
 (0)