Add a unstable-disable-block-count-check feature that removes the block count check

Upstream PR: https://github.com/littlefs-project/littlefs/pull/584 introduced a check
that the block count matches the superblock.

However that can cause some issues for filesystem that were formatted with a wrong block count
and later corrected.
This commit is contained in:
Sosthène Guédon
2025-04-16 11:04:07 +02:00
committed by sosthene-nitrokey
parent fa642ad1a5
commit 55d0f97434
3 changed files with 81 additions and 20 deletions
+2
View File
@@ -19,3 +19,5 @@ trace = []
malloc = []
software-intrinsics = []
multiversion = []
unstable-disable-block-count-check = []
+48 -20
View File
@@ -1,14 +1,61 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
// Patch lfs.h to remove the lfs_util import because clang fails to locate the
// libraries for the custom target (especially string.h)
// Compilation before that succeeds because it's using gcc,
// which comes as a distribution with these utils.
// Turns out lfs_utils is not used in lfs.h, and clang properly finds stdint.h and stdbool,
// but not string.h
let lfs_h = std::fs::read_to_string("littlefs/lfs.h").expect("Reading lfs.h succeeds");
println!("cargo::rerun-if-changed=littlefs/lfs.h");
let out_lfs_h = out_path.join("lfs.h");
std::fs::write(
&out_lfs_h,
lfs_h.replace(
r##"#include "lfs_util.h""##,
"#include <stdint.h>\n#include <stdbool.h>",
),
)
.expect("Failed to write lfs.h");
// maybe patch lfs.c to remove the mount check for the block count
println!("cargo::rerun-if-changed=littlefs/lfs.c");
let out_lfs_c = out_path.join("lfs.c");
if cfg!(feature = "unstable-disable-block-count-check") {
println!("cargo::rerun-if-changed=remove-mount-check.patch");
assert!(
Command::new("patch")
.args([
"littlefs/lfs.c",
"-o",
out_lfs_c.to_str().unwrap(),
"remove-mount-check.patch"
])
.spawn()
.unwrap()
.wait()
.unwrap()
.success(),
"Failed to apply patch"
)
} else {
std::fs::copy("littlefs/lfs.c", out_path.join("lfs.c")).unwrap();
}
let mut builder = cc::Build::new();
let builder = builder
.flag("-std=c99")
.flag("-DLFS_NO_DEBUG")
.flag("-DLFS_NO_WARN")
.flag("-DLFS_NO_ERROR")
.file("littlefs/lfs.c")
.include(&out_path)
.include("littlefs")
.file(out_lfs_c)
.file("littlefs/lfs_util.c")
.file("string.c");
@@ -29,25 +76,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
builder.compile("lfs-sys");
// Patch lfs.h to remove the lfs_util import because clang fails to locate the
// libraries for the custom target (especially string.h)
// Compilation before that succeeds because it's using gcc,
// which comes as a distribution with these utils.
// Turns out lfs_utils is not used in lfs.h, and clang properly finds stdint.h and stdbool,
// but not string.h
let lfs_h = std::fs::read_to_string("littlefs/lfs.h").expect("Reading lfs.h succeeds");
println!("cargo::rerun-if-changed=littlefs/lfs.h");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let out_lfs_h = out_path.join("lfs.h");
std::fs::write(
&out_lfs_h,
lfs_h.replace(
r##"#include "lfs_util.h""##,
"#include <stdint.h>\n#include <stdbool.h>",
),
)
.expect("Failed to write lfs.h");
let bindgen = bindgen::Builder::default()
.header(out_lfs_h.into_os_string().into_string().unwrap())
.clang_arg("-std=c99")
+31
View File
@@ -0,0 +1,31 @@
--- lfs.c 2025-04-14 12:03:45.959258416 +0200
+++ lfs.c.patched 2025-04-14 12:03:23.044370382 +0200
@@ -4521,15 +4521,20 @@
}
// this is where we get the block_count from disk if block_count=0
- if (lfs->cfg->block_count
- && superblock.block_count != lfs->cfg->block_count) {
- LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
- superblock.block_count, lfs->cfg->block_count);
- err = LFS_ERR_INVAL;
- goto cleanup;
- }
+ //
+ // if (lfs->cfg->block_count
+ // && superblock.block_count != lfs->cfg->block_count) {
+ // LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
+ // superblock.block_count, lfs->cfg->block_count);
+ // err = LFS_ERR_INVAL;
+ // goto cleanup;
+ // }
- lfs->block_count = superblock.block_count;
+ if (lfs->cfg->block_count) {
+ lfs->block_count = lfs->cfg->block_count;
+ } else {
+ lfs->block_count = superblock.block_count;
+ }
if (superblock.block_size != lfs->cfg->block_size) {
LFS_ERROR("Invalid block size (%"PRIu32" != %"PRIu32")",