Re: Panic: cache_vop_rename: lingering negative entry
Jan Martin Mikkelsen <[email protected]>
| Newsgroups | gmane.os.freebsd.current |
|---|---|
| Message-ID | <[email protected]> |
> On 14. Apr 2026, at 17:57, Jan Martin Mikkelsen <[email protected]> wrote: > > >> On 14 Apr 2026, at 11:52, Konstantin Belousov <[email protected]> wrote: >> >> On Tue, Apr 14, 2026 at 11:45:08AM +0200, Jan Martin Mikkelsen wrote: >>> >>>> On 13 Apr 2026, at 22:13, Konstantin Belousov <[email protected]> wrote: >>>> >>>> On Mon, Apr 13, 2026 at 07:12:32PM +0200, Jan Martin Mikkelsen wrote: >>>>> >>>>>> On 7 Apr 2026, at 20:20, Jan Martin Mikkelsen <[email protected]> wrote: >>>>>> >>>>>> On 7 Apr 2026, at 18:53, Konstantin Belousov <[email protected]> wrote: >>>>>>> >>>>>>> On Tue, Apr 07, 2026 at 05:02:05PM +0200, Jan Martin Mikkelsen wrote: >>>>>>>> Hi, >>>>>>>> >>>>>>>> I am consistently getting the panic below while building lang/perl5.42. This is the command from the perl build that triggers the panic: >>>>>>>> >>>>>>>> /usr/bin/strip /ports-work/usr/ports/lang/perl5.42/work/stage/usr/local/bin/perl5.42.0 >>>>>>>> >>>>>>>> CURRENT on aarch64, with a kernel from last week, also with a later one from the weekend. A kernel from mid-January worked fine. >>>>>>>> >>>>>>>> I can reproduce on demand, no parallelism in the build required. >>>>>>>> >>>>>>>> Does this look familiar to anyone? >>>>>>>> >>>>>>>> panic: cache_vop_rename: lingering negative entry >>>>>>>> cpuid = 4 >>>>>>>> time = 1775410763 >>>>>>>> KDB: stack backtrace: >>>>>>>> db_trace_self() at db_trace_self >>>>>>>> db_trace_self_wrapper() at db_trace_self_wrapper+0x38 >>>>>>>> vpanic() at vpanic+0x1a0 >>>>>>>> panic() at panic+0x48 >>>>>>>> cache_vop_rename() at cache_vop_rename+0xb0 >>>>>>>> zfs_do_rename() at zfs_do_rename+0xafc >>>>>>>> zfs_freebsd_rename() at zfs_freebsd_rename+0x5c >>>>>>>> VOP_RENAME_APV() at VOP_RENAME_APV+0x44 >>>>>>>> kern_renameat () at kern_renameat+0x574 >>>>>>>> do_el0_sync() at do_el0_sync+0x5f8 >>>>>>>> handle_el0_sync() at handle_el0_sync+0x4c >>>>>>>> --- exception, esr 0x56000000 >>>>>>>> KDB: enter: panic >>>>>>>> [ thread pid 81230 tid 101738 ] >>>>>>>> Stopped at kdb_enter+0x48: str xzr, [x19, #3072] >>>>>>> >>>>>>> Is it reproducable on UFS and/or tmpfs? >>>>>> >>>>>> Successful completion (no panic) when the work directory is on UFS, and when the work directory is on tmpfs. I didn’t try multiple times, but it never works on ZFS. >>>>> >>>>> The panic consistently reproduces on a ZFS filesystem with the properties “utf8only=on” and "normalization=formD”. >>>>> >>>>> A ZFS file system with “utf8only=off” and "normalization=none” works fine. >>>>> >>>>> As far as I can see, strip makes a simple rename(2) call, and testing rename(2) works fine (as expected). Running the same strip command on the same files on a fresh system works fine. >>>>> >>>>> The smallest reproducer I have at the moment is building lang/perl5.42.0 with a workdir on a ZFS filesystem enforcing UTF8. >>>> >>>> I am now sure that the reason is that the options you used cause the same >>>> inode to have more than one name (but not hardlinks). I remember that >>>> zfs had option to be case-insensitive, but I may mis-remember. >>>> >>>> The solution, in any case, is to either stop using namecache when these >>>> options are activated, or at least purge all cached entries that has the >>>> given dst when the dst vnode is renamed or deleted. >>>> >>>> Somebody who knows zfs would be needed to make the change. >>> >>> I had a look at the ZFS source, and found this: >>> >>> /* >>> * Only use the name cache if we are looking for a >>> * name on a file system that does not require normalization >>> * or case folding. We can also look there if we happen to be >>> * on a non-normalizing, mixed sensitivity file system IF we >>> * are looking for the exact name (which is always the case on >>> * FreeBSD). >>> */ >>> zfsvfs->z_use_namecache = !zfsvfs->z_norm || >>> ((zfsvfs->z_case == ZFS_CASE_MIXED) && >>> !(zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER)); >>> >>> >>> The call to cache_vop_rename() which causes the panic is not protected by an “if (zfsvfs->z_use_namecache)”, unlike the rest of the code that uses that to decide whether or not to use the namecache. >>> >>> Elsewhere in zfs_vnops_os.c, there is another call to a cache_vop* function, which is protected by a test: >>> >>> if (zfsvfs->z_use_namecache) >>> cache_vop_rmdir(dvp, vp); >>> >>> It seems to me that this patch could resolve the problem. Does this seem reasonable? >>> >>> --- a/src/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c 2026-03-28 20:55:06.000000000 1100 >>> +++ b/src/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c 2026-03-28 20:55:06.000000000 1100 >>> @@ -3524,7 +3524,7 @@ >>> ZRENAMING, NULL)); >>> } >>> } >>> - if (error == 0) { >>> + if (error == 0 && zfsvfs->z_use_namecache) { >>> cache_vop_rename(sdvp, *svpp, tdvp, *tvpp, scnp, tcnp); >>> } >>> } >>> >> >> Yes, but please test. >> If works for you, please either create a Github PR or a review on the >> FreeBSD' phab. > > That does seem to fix the panic. I’ll do a GitHub PR. Thanks for your help. https://github.com/openzfs/zfs/pull/18430