Skip to content

Commit 28c3564

Browse files
Add a unstable-disable-block-count-check feature that removes the block count check
Upstream PR: littlefs-project/littlefs#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.
1 parent fa642ad commit 28c3564

File tree

3 files changed

+79
-20
lines changed

3 files changed

+79
-20
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ trace = []
1919
malloc = []
2020
software-intrinsics = []
2121
multiversion = []
22+
23+
unstable-disable-block-count-check = []

build.rs

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,61 @@
11
use std::env;
22
use std::path::PathBuf;
3+
use std::process::Command;
34

45
fn main() -> Result<(), Box<dyn std::error::Error>> {
6+
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
7+
8+
// Patch lfs.h to remove the lfs_util import because clang fails to locate the
9+
// libraries for the custom target (especially string.h)
10+
// Compilation before that succeeds because it's using gcc,
11+
// which comes as a distribution with these utils.
12+
// Turns out lfs_utils is not used in lfs.h, and clang properly finds stdint.h and stdbool,
13+
// but not string.h
14+
let lfs_h = std::fs::read_to_string("littlefs/lfs.h").expect("Reading lfs.h succeeds");
15+
println!("cargo::rerun-if-changed=littlefs/lfs.h");
16+
let out_lfs_h = out_path.join("lfs.h");
17+
std::fs::write(
18+
&out_lfs_h,
19+
lfs_h.replace(
20+
r##"#include "lfs_util.h""##,
21+
"#include <stdint.h>\n#include <stdbool.h>",
22+
),
23+
)
24+
.expect("Failed to write lfs.h");
25+
26+
// maybe patch lfs.c to remove the mount check for the block count
27+
println!("cargo::rerun-if-changed=littlefs/lfs.c");
28+
let out_lfs_c = out_path.join("lfs.c");
29+
if cfg!(feature = "unstable-disable-block-count-check") {
30+
println!("cargo::rerun-if-changed=remove-mount-check.patch");
31+
assert!(
32+
Command::new("patch")
33+
.args([
34+
"littlefs/lfs.c",
35+
"-o",
36+
&format!("{}", out_lfs_c.to_str().unwrap()),
37+
"remove-mount-check.patch"
38+
])
39+
.spawn()
40+
.unwrap()
41+
.wait()
42+
.unwrap()
43+
.success(),
44+
"Failed to apply patch"
45+
)
46+
} else {
47+
std::fs::copy("littlefs/lfs.c", out_path.join("lfs.c")).unwrap();
48+
}
49+
550
let mut builder = cc::Build::new();
651
let builder = builder
752
.flag("-std=c99")
853
.flag("-DLFS_NO_DEBUG")
954
.flag("-DLFS_NO_WARN")
1055
.flag("-DLFS_NO_ERROR")
11-
.file("littlefs/lfs.c")
56+
.include(&out_path)
57+
.include("littlefs")
58+
.file(out_lfs_c)
1259
.file("littlefs/lfs_util.c")
1360
.file("string.c");
1461

@@ -29,25 +76,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
2976

3077
builder.compile("lfs-sys");
3178

32-
// Patch lfs.h to remove the lfs_util import because clang fails to locate the
33-
// libraries for the custom target (especially string.h)
34-
// Compilation before that succeeds because it's using gcc,
35-
// which comes as a distribution with these utils.
36-
// Turns out lfs_utils is not used in lfs.h, and clang properly finds stdint.h and stdbool,
37-
// but not string.h
38-
let lfs_h = std::fs::read_to_string("littlefs/lfs.h").expect("Reading lfs.h succeeds");
39-
println!("cargo::rerun-if-changed=littlefs/lfs.h");
40-
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
41-
let out_lfs_h = out_path.join("lfs.h");
42-
std::fs::write(
43-
&out_lfs_h,
44-
lfs_h.replace(
45-
r##"#include "lfs_util.h""##,
46-
"#include <stdint.h>\n#include <stdbool.h>",
47-
),
48-
)
49-
.expect("Failed to write lfs.h");
50-
5179
let bindgen = bindgen::Builder::default()
5280
.header(out_lfs_h.into_os_string().into_string().unwrap())
5381
.clang_arg("-std=c99")

remove-mount-check.patch

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--- lfs.c 2025-04-14 12:03:45.959258416 +0200
2+
+++ lfs.c.patched 2025-04-14 12:03:23.044370382 +0200
3+
@@ -4521,15 +4521,18 @@
4+
}
5+
6+
// this is where we get the block_count from disk if block_count=0
7+
- if (lfs->cfg->block_count
8+
- && superblock.block_count != lfs->cfg->block_count) {
9+
- LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
10+
- superblock.block_count, lfs->cfg->block_count);
11+
- err = LFS_ERR_INVAL;
12+
- goto cleanup;
13+
- }
14+
+ //
15+
+ // if (lfs->cfg->block_count
16+
+ // && superblock.block_count != lfs->cfg->block_count) {
17+
+ // LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
18+
+ // superblock.block_count, lfs->cfg->block_count);
19+
+ // err = LFS_ERR_INVAL;
20+
+ // goto cleanup;
21+
+ // }
22+
23+
- lfs->block_count = superblock.block_count;
24+
+ if (lfs->cfg->block_count) {
25+
+ lfs->block_count = lfs->cfg->block_count;
26+
+ }
27+
28+
if (superblock.block_size != lfs->cfg->block_size) {
29+
LFS_ERROR("Invalid block size (%"PRIu32" != %"PRIu32")",

0 commit comments

Comments
 (0)