Skip to content

Commit

Permalink
storage/stream: fix possible unaligned write on buffer flush
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
  • Loading branch information
nvlsianpu authored and Oleg committed May 30, 2020
1 parent edbe5a5 commit 9cd3d35
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 9cd3d35

Please sign in to comment.