Repository navigation
fs/mtd: clean up FTL allocations on initialization failure - #7549
Conversation
|
|
||
| #ifdef CONFIG_DRVR_WRITEBUFFER | ||
| DEBUGASSERT(rwb->wrflush != NULL); | ||
| DEBUGASSERT(rwb->wrmaxblocks == 0 || rwb->wrflush != NULL); |
There was a problem hiding this comment.
rwb->wrmaxblocks == 0 will not come forever, because rwb->wrmaxblocks is same as dev->blkper.
blkper is calculated based on size of eraseblock & read/write block.
Each of flash driver based on MTD using constant value, I mean defined value.
If you really want to check wrmaxblocks , then it need to be checked after block driver check geometry(for example, https://github.com/Samsung/TizenRT/blob/master/os/fs/driver/mtd/ftl.c#L526), not here.
There was a problem hiding this comment.
Thanks. I removed the wrmaxblocks == 0 || check and placed the callback assertion inside the active write-buffer branch. The FTL read-ahead-only configuration can leave the write direction inactive.
| DEBUGASSERT(rwb->rhreload != NULL); | ||
| DEBUGASSERT(rwb->rhmaxblocks == 0 || rwb->rhreload != NULL); | ||
| rwb->rhbuffer = NULL; | ||
| if (rwb->rhmaxblocks > 0) { |
There was a problem hiding this comment.
half is right, but half is wrong. please see line 655. both of sem can be initialize at line 686
There was a problem hiding this comment.
Thanks. The semaphores for enabled buffers are now initialized only after all enabled buffer allocations succeed. If read-ahead allocation fails, rwb_initialize() frees the earlier write buffer before returning.
| * the user buffer. | ||
| */ | ||
|
|
||
| DEBUGASSERT(rwb->rhreload != NULL); |
There was a problem hiding this comment.
It's not necessary, rwb->rhreload already checked in rwb_initialize.
if rwb_initialize failed because rwb->rhreload is null then block driver will not be registered.
In this case pseudo file system will not include path of ftl driver, so file operation(open, read, write) never be called.
There was a problem hiding this comment.
Removed the extra direct read/write fallback callback assertions. Active callbacks are checked during rwb_initialize() before block-driver registration.
| ret = rwb_initialize(&dev->rwb); | ||
| if (ret < 0) { | ||
| dbg("ERROR: rwb_initialize failed: %d\n", ret); | ||
| rwb_uninitialize(&dev->rwb); |
There was a problem hiding this comment.
we clenad resource if rwb_initialize failed, so I think we should not call rwb_uninitialize here.
There was a problem hiding this comment.
Agreed. FTL no longer calls rwb_uninitialize() after rwb_initialize() fails. The helper rolls back its partial buffer allocation, while FTL frees its erase buffer and device. Registration failure still uses rwb_uninitialize().
| dbg("ERROR: rwb_initialize failed: %d\n", ret); | ||
| rwb_uninitialize(&dev->rwb); | ||
| #ifdef CONFIG_FS_WRITABLE | ||
| kmm_free(dev->eblock); |
There was a problem hiding this comment.
can you please consider something more?
I think early-return is good option for this code (line 515);
There was a problem hiding this comment.
Applied the early return when the FTL device allocation fails. It returns -ENOMEM as before, and the remaining initialization keeps the same ownership and cleanup paths.
| if (ret < 0) { | ||
| dbg("ERROR: register_blockdriver failed: %d\n", -ret); | ||
| #ifdef CONFIG_FS_WRITABLE | ||
| kmm_free(dev->eblock); |
There was a problem hiding this comment.
please add below more.
dev->eblock = NULL;
dev->block_map = NULL;
There was a problem hiding this comment.
Added dev->eblock = NULL and dev->block_map = NULL immediately after their respective frees on registration failure.
Taejun-Kwon
left a comment
There was a problem hiding this comment.
thanks for your effort.
|
|
||
| #ifdef CONFIG_DRVR_WRITEBUFFER | ||
| if (rwb->wrmaxblocks > 0) { | ||
| DEBUGASSERT(rwb->wrflush != NULL); |
There was a problem hiding this comment.
then line 623 can be moved to between line 629 & 630 to reduce code line. Same opinion for rhbuffer.
There was a problem hiding this comment.
Moved the wrbuffer and rhbuffer NULL assignments before their buffer checks and removed the duplicate assignments. Thanks for the suggestion.
fs/mtd: clean up FTL allocations on initialization failure
Fixes #7442.
Problem
ftl_initialize()andftl_nand_initialize()allocate child buffers before registering the block driver. Several later failure paths free only the device structure.register_blockdriver()assigns the private device pointer to an inode only afterinode_reserve()succeeds, so the initializer still owns those buffers when registration fails.Changes
rwb_initialize()releases the previously allocated write buffer; the FTL caller then releases only its own erase buffer and device.On successful registration, the initializer leaves the device and its buffers in place. Existing return codes and read/write logic are unchanged.
Validation
An isolated macOS host harness compiled the actual three changed C source files with stubbed kernel interfaces, AddressSanitizer, and UndefinedBehaviorSanitizer. It injects allocation, geometry, and registration failures and counts live allocations, semaphore initialization/destruction, and double frees.
git diff --checkpassed.The global read-ahead-only configuration remains outside the tested matrix. Pristine master and the initially submitted patch produced the same five host compilation errors in existing write-buffer timeout helpers that reference write-buffer fields while global write buffering is disabled. This pre-existing build problem is outside this fix; the revised patch was not separately compiled in that configuration.
This validation does not include a TizenRT firmware build, QEMU/board execution, real flash operations, the real kernel workqueue,
sem_init()failure injection, or field frequency/impact measurements. The existingle_tctests do not provide deterministic failure injection for this private initializer, so the host harness is not presented as a native TizenRT regression test.AI assistance: OpenAI Codex helped analyze the code, prepare the local patch, and build the isolated harness. The test conditions and unverified areas are stated above for maintainer review.