From 06827ecd14d82babe8b95dfa315261d3f6175127 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 25 May 2020 12:59:46 +0200 Subject: [PATCH] storage/stream: fix possible unaligned write on buffer 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 #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 --- subsys/storage/stream/stream_flash.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/subsys/storage/stream/stream_flash.c b/subsys/storage/stream/stream_flash.c index 86e12288226..847cb9863eb 100644 --- a/subsys/storage/stream/stream_flash.c +++ b/subsys/storage/stream/stream_flash.c @@ -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; @@ -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); } @@ -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++) {