Skip to content

Commit

Permalink
[nrf fromlist] storage/stream: fix possible unaligned write on buffer…
Browse files Browse the repository at this point in the history
… flush

On buffer flush request it is very probably that write buffer
contains amount of data which is non write-block-size aligned.
Flash memory need to be write at minimal by write-block-size chunks.
This patch addresses mechanism which ensure such behavior by adding
missing bytes.

fixes zephyrproject-rtos#25471

streamer buffer size should be multiple write-block-size of
the flash device in order to avoid unaligned flash write
request.

upstream: zephyrproject-rtos#25584

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
  • Loading branch information
nvlsianpu authored and joerchan committed May 27, 2020
1 parent 35dd9b6 commit 020b505
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions subsys/storage/stream/stream_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const u8_t *data,
int processed = 0;
int rc = 0;
int buf_empty_bytes;
size_t fill_length;
u8_t filler;

if (!ctx || !data) {
return -EFAULT;
Expand Down Expand Up @@ -144,6 +146,27 @@ int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const u8_t *data,
}

if (flush && ctx->buf_bytes > 0) {
fill_length = flash_get_write_block_size(ctx->fdev);
if (ctx->buf_bytes % fill_length) {
fill_length -= ctx->buf_bytes % fill_length;
/*
* Leverage the fact that unwritten memory
* should be erased in order to get the erased
* byte-value.
*/
rc = flash_read(ctx->fdev,
ctx->offset + ctx->bytes_written,
(void *)&filler,
1);

if (rc != 0) {
return rc;
}

memset(ctx->buf + ctx->buf_bytes, filler, fill_length);
ctx->buf_bytes += fill_length;
}

rc = flash_sync(ctx);
}

Expand All @@ -168,6 +191,11 @@ int stream_flash_init(struct stream_flash_ctx *ctx, struct device *fdev,
const struct flash_pages_layout *layout;
const struct flash_driver_api *api = fdev->driver_api;

if (buf_len % flash_get_write_block_size(fdev)) {
LOG_ERR("Buffer size is not aligned to minimal write-block-size");
return -EFAULT;
}

/* Calculate the total size of the flash device */
api->page_layout(fdev, &layout, &layout_size);
for (int i = 0; i < layout_size; i++) {
Expand Down

0 comments on commit 020b505

Please sign in to comment.