I tried to use NANDFS instead of UFS to keep an SD-Card longer alife. I have tested it on 10.1 -> amd64 (seems working) and 11.0 -> amd64 and armv6 (both making panic) root@test:~ # dd if=/dev/zero of=/nandtest bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes transfered in 17.864829 secs (63667521 bytes/sec) root@test:~ # mdconfig -a -t vnode /nandtest md0 root@test:~ # newfs_nandfs /dev/md0 filesystem parametsers: blocksize: 0x1000 sectorsize: 0x200 erasesize: 0x20000 mediasize: 0x40000000 segment size: 0x20000 blocks per segment: 0x20 filesystem created successfully total segments: 0x1ffa valid segments: 0x1ffa total space: 1023 MB free: 1023 MB root@test:~ # kldload nandfs root@test:~ # mount -t nandfs /dev/md0 WARNING: NANDFS is considered to be a highly experimental feature in FreeBSD NULL mp in getnewvnode() NULL mp in getnewvnode() NULL mp in getnewvnode() NULL mp in getnewvnode() panic: bsize == 0, check bo->bo_size cpuid = 2 KDB: stack backtrace: db_trace_self_wrapper() ad db_trace_self_wrapper+0x2b/frame 0xfffffe01207f2220 vpanic() at vpanic+0x189/frame 0xfffffe01207f20a0 kassert_panic() at kassert_panic+0x132/frame 0xfffffe01207f2310 getblk() at getblk+0x850/frame 0xfffffe01207f23d0 breadn_flags() at dreadn_flags+0x2d/frame 0xfffffe01207f2410 nandfs_bread() at nandfs_bread+0x6e/frame 0xfffffe01207f2460 nandfs_get_seg_stat() at nandfs_get_seg_stat+0xa7/frame 0xfffffe01207f24e0 nandfs_mount() at nandfs_mount+0x1f62/frame 0xfffffe01207f26d0 vfs_donmount() at vfs_donmount+0x1330/frame 0xfffffe01207f2aa0 sys_nmount() at sys_nmount+0x72/frame 0xfffffe01207f2ae0 amd64_syscall() at amd64_syscall+0x27f/frame 0xfffffe01207f2bf0 Xfast_syscall() at Xfast_syscall+0xfb/frame 0xfffffe01207f2bf0 --- syscall (378, FreeBSD ELF64, sys_nmount) rip = 0x800aab9ca, rsb = 0x7fffffffdb58, rbp = 0x7fffffffffe0c0 --- KDB: enter: panic
After some research i figured something out. Seems the used buffers are moved from in-core to not-in-core. The function "getblk" in src/sys/kern/vfs_bio.c (line 3064-3308) now needs to create a new buffer instead of using a existing in-core-buffer. This requires an correct set sector size in line 3230, but it is 0. Index: src/sys/fs/nandfs/nandfs_subr.c =================================================================== --- src/sys/fs/nandfs/nandfs_subr.c (revision 280320) +++ src/sys/fs/nandfs/nandfs_subr.c (working copy) @@ -210,6 +210,9 @@ DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node), blocknr)); + if (node->nn_vnode->v_bufobj.bo_bsize == 0) + node->nn_vnode->v_bufobj.bo_bsize = 512; + error = bread(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize, cred, bpp); This does the job, it is now working, but i don't belive it's the right way to do this.
^Triage: note that this PR contains an inline patch.
Isn't NANDFS removed from FreeBSD before stable/13 was branched? https://cgit.freebsd.org/src/commit/?id=f5a95d9a07941650493461c255408f5727d0638b https://www.freebsd.org/security/unsupported/ I think no supported version of FreeBSD has the NANDFS filesystem. A quick 'find stable/13 -iname "*nand*"' does not give me any relevant files. The file of the inline patch in comment #1 does not exist either.
NANDFS had heap big time issues, not least was that the groomer was moved into the kernel. This normally wouldn't be terrible, but here there were two problems: locking was all screwed up by it (or was just implemented badly) and it always groomed, even when there was no new traffic, so the groomer slowly would rewrite the NAND over and over and over again. I wore out a MLC part while playing with it and tracked the issue down to this... That was in the FreeBSD 8 or 9 time frame and by FreeBSD 10 it wasn't working at all (even with this patch) and had all kinds of lock order issues because the locking protocols evolved substantially over time, but no changes were made here. It's kind of a bummer, but doing a good nandfs takes a lot of time and effort and you have to keep up all the time on the latest nand parts / soc offload engines / etc. And we had none of that.