Skip to content

Commit c011646

Browse files
tmon-nordiccarlescufi
authored andcommitted
drivers: flashdisk: check partition constraints
Fail with error if any of flashdisk partition assumptions are not met: * uniform page size through the whole partition * flashdisk starts at page boundary * flashdisk ends at page boundary Read-only flashdisks are not subject to above conditions because the cache buffer is not used for read-only flashdisks. The checks can be disabled via Kconfig option to save code space. Signed-off-by: Tomasz Moń <[email protected]>
1 parent 8981015 commit c011646

File tree

2 files changed

+69
-27
lines changed

2 files changed

+69
-27
lines changed

drivers/disk/Kconfig.flash

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ config DISK_DRIVER_FLASH
99
Flash device is used for the file system.
1010

1111
if DISK_DRIVER_FLASH
12+
13+
config FLASHDISK_VERIFY_PAGE_LAYOUT
14+
bool "Verify flashdisk partition layout"
15+
default y
16+
help
17+
Enable runtime zephyr,flash-disk partition page layout constraints
18+
verification. Disable to reduce code size.
19+
1220
module = FLASHDISK
1321
module-str = flashdisk
1422
source "subsys/logging/Kconfig.template.log_config"

drivers/disk/flashdisk.c

+61-27
Original file line numberDiff line numberDiff line change
@@ -47,52 +47,86 @@ static int disk_flash_access_status(struct disk_info *disk)
4747
return DISK_STATUS_OK;
4848
}
4949

50-
static int disk_flash_access_init(struct disk_info *disk)
50+
static int flashdisk_init_runtime(struct flashdisk_data *ctx,
51+
const struct flash_area *fap)
5152
{
52-
struct flashdisk_data *ctx;
53-
const struct flash_area *fap;
5453
int rc;
5554
struct flash_pages_info page;
55+
off_t offset;
5656

57-
ctx = CONTAINER_OF(disk, struct flashdisk_data, info);
58-
59-
rc = flash_area_open(ctx->area_id, &fap);
60-
if (rc < 0) {
61-
LOG_ERR("Flash area %u open error %d", ctx->area_id, rc);
62-
return rc;
63-
}
64-
65-
k_mutex_lock(&ctx->lock, K_FOREVER);
66-
67-
disk->dev = flash_area_get_device(fap);
68-
69-
rc = flash_get_page_info_by_offs(disk->dev, ctx->offset, &page);
57+
rc = flash_get_page_info_by_offs(ctx->info.dev, ctx->offset, &page);
7058
if (rc < 0) {
7159
LOG_ERR("Error %d while getting page info", rc);
72-
goto end;
60+
return rc;
7361
}
7462

7563
ctx->page_size = page.size;
76-
LOG_INF("Initialize device %s", disk->name);
64+
LOG_INF("Initialize device %s", ctx->info.name);
7765
LOG_INF("offset %lx, sector size %zu, page size %zu, volume size %zu",
7866
(long)ctx->offset, ctx->sector_size, ctx->page_size, ctx->size);
7967

8068
if (ctx->cache_size == 0) {
81-
LOG_INF("%s is read-only", disk->name);
82-
} else if (ctx->page_size > ctx->cache_size) {
69+
/* Read-only flashdisk, no flash partition constraints */
70+
LOG_INF("%s is read-only", ctx->info.name);
71+
return 0;
72+
}
73+
74+
if (IS_ENABLED(CONFIG_FLASHDISK_VERIFY_PAGE_LAYOUT)) {
75+
if (ctx->offset != page.start_offset) {
76+
LOG_ERR("Disk %s does not start at page boundary",
77+
ctx->info.name);
78+
return -EINVAL;
79+
}
80+
81+
offset = ctx->offset + page.size;
82+
while (offset < ctx->offset + ctx->size) {
83+
rc = flash_get_page_info_by_offs(ctx->info.dev, offset, &page);
84+
if (rc < 0) {
85+
LOG_ERR("Error %d while getting page info", rc);
86+
return rc;
87+
}
88+
if (page.size != ctx->page_size) {
89+
LOG_ERR("Non-uniform page size is not supported");
90+
return rc;
91+
}
92+
offset += page.size;
93+
}
94+
95+
if (offset != ctx->offset + ctx->size) {
96+
LOG_ERR("Last page crossess disk %s boundary",
97+
ctx->info.name);
98+
return -EINVAL;
99+
}
100+
}
101+
102+
if (ctx->page_size > ctx->cache_size) {
83103
LOG_ERR("Cache too small (%zu needs %zu)",
84104
ctx->cache_size, ctx->page_size);
85-
rc = -ENOMEM;
86-
goto end;
105+
return -ENOMEM;
87106
}
88107

89-
if (ctx->cache_valid && ctx->cache_dirty) {
90-
LOG_ERR("Discarding %s dirty cache", disk->name);
91-
ctx->cache_valid = false;
108+
return 0;
109+
}
110+
111+
static int disk_flash_access_init(struct disk_info *disk)
112+
{
113+
struct flashdisk_data *ctx;
114+
const struct flash_area *fap;
115+
int rc;
116+
117+
ctx = CONTAINER_OF(disk, struct flashdisk_data, info);
118+
119+
rc = flash_area_open(ctx->area_id, &fap);
120+
if (rc < 0) {
121+
LOG_ERR("Flash area %u open error %d", ctx->area_id, rc);
122+
return rc;
92123
}
93124

94-
rc = 0;
95-
end:
125+
k_mutex_lock(&ctx->lock, K_FOREVER);
126+
127+
disk->dev = flash_area_get_device(fap);
128+
129+
rc = flashdisk_init_runtime(ctx, fap);
96130
if (rc < 0) {
97131
flash_area_close(fap);
98132
}

0 commit comments

Comments
 (0)