storage/stream/flash: Fix flash_sync updating bytes_written on failure
The flash_sync function is able to call, if specified, write verification callback to check whether data flash has been correctly written to a flash. Part of that procedure is to read date back of the flash and call the verification callback on the buffer; in case if the read would fail, the flash_sync would return, with an error code, without updating stream_flash_ctx. The same logic should be applied to failed verification, but, due to missing return, the stream_flash_ctx gets updated with probably incorrectly written bytes added to total bytes_written and buf_bytes, representing number of bytes awaiting in buffer, being zeroed. Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
parent
94968dfee4
commit
cfb056901c
2 changed files with 35 additions and 0 deletions
|
@ -98,6 +98,7 @@ static int flash_sync(struct stream_flash_ctx *ctx)
|
||||||
rc = ctx->callback(ctx->buf, ctx->buf_bytes, write_addr);
|
rc = ctx->callback(ctx->buf, ctx->buf_bytes, write_addr);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
LOG_ERR("callback failed: %d", rc);
|
LOG_ERR("callback failed: %d", rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,6 +270,16 @@ static void test_stream_flash_buf_size_greater_than_page_size(void)
|
||||||
zassert_true(rc < 0, "expected failure");
|
zassert_true(rc < 0, "expected failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bad_read(const struct device *dev, off_t off, void *data, size_t len)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fake_write(const struct device *dev, off_t off, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_stream_flash_buffered_write_callback(void)
|
static void test_stream_flash_buffered_write_callback(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -304,6 +314,30 @@ static void test_stream_flash_buffered_write_callback(void)
|
||||||
cb_buf = NULL; /* Don't verify other parameters of the callback */
|
cb_buf = NULL; /* Don't verify other parameters of the callback */
|
||||||
rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN, true);
|
rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN, true);
|
||||||
zassert_equal(rc, -EFAULT, "expected failure from callback");
|
zassert_equal(rc, -EFAULT, "expected failure from callback");
|
||||||
|
/* Expect that the BUF_LEN of bytes got stuck in buffer as the verification callback
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
zassert_equal(ctx.buf_bytes, BUF_LEN, "Expected bytes to be left in buffer");
|
||||||
|
|
||||||
|
struct device fake_dev = *ctx.fdev;
|
||||||
|
struct flash_driver_api fake_api = *(struct flash_driver_api *)ctx.fdev->api;
|
||||||
|
struct stream_flash_ctx bad_ctx = ctx;
|
||||||
|
struct stream_flash_ctx cmp_ctx;
|
||||||
|
|
||||||
|
fake_api.read = bad_read;
|
||||||
|
/* Using fake write here because after previous write, with faked callback failure,
|
||||||
|
* the flash is already written and real flash_write would cause failure.
|
||||||
|
*/
|
||||||
|
fake_api.write = fake_write;
|
||||||
|
fake_dev.api = &fake_api;
|
||||||
|
bad_ctx.fdev = &fake_dev;
|
||||||
|
/* Triger erase attempt */
|
||||||
|
cmp_ctx = bad_ctx;
|
||||||
|
/* Just flush buffer */
|
||||||
|
rc = stream_flash_buffered_write(&bad_ctx, write_buf, 0, true);
|
||||||
|
zassert_equal(rc, -EINVAL, "expected failure from flash_sync", rc);
|
||||||
|
zassert_equal(ctx.buf_bytes, BUF_LEN, "Expected bytes to be left in buffer");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_stream_flash_flush(void)
|
static void test_stream_flash_flush(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue