Bug 275870 - [unionfs] [zfs] kernel panic on umount
Summary: [unionfs] [zfs] kernel panic on umount
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 14.0-RELEASE
Hardware: Any Any
: --- Affects Many People
Assignee: Jason A. Harmening
URL:
Keywords: crash
Depends on:
Blocks:
 
Reported: 2023-12-21 18:02 UTC by Karlo Miličević
Modified: 2024-03-10 02:08 UTC (History)
4 users (show)

See Also:


Attachments
Suggested patch, this fixed the panic in local testing. (5.71 KB, patch)
2023-12-22 03:30 UTC, Jason A. Harmening
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Karlo Miličević 2023-12-21 18:02:00 UTC
If you do a ZFS rollback which removes a unionfs mountpoint and umount mountpoint after that, 14.0 kernel will panic.
In 13.0 it works fine - it is unmounted even though the directory was rolled back.

I provide a small script that reproduces the problem:

#!/bin/sh
zfs create zroot/var/repro
zfs snapshot zroot/var/repro@clean
cd /var/repro
mkdir a b
mount_unionfs a b
zfs rollback zroot/var/repro@clean
umount /var/repro/b
Comment 1 Jason A. Harmening freebsd_committer freebsd_triage 2023-12-22 03:30:21 UTC
Created attachment 247192 [details]
Suggested patch, this fixed the panic in local testing.
Comment 2 Jason A. Harmening freebsd_committer freebsd_triage 2023-12-22 03:33:37 UTC
It looks like this was caused by the vfs_unregister_upper() calls I added in 14.  I'm a bit surprised that zfs rollback obliterates the v_mount field of the upper/lower vnodes, but then I'm not familiar with that code.  In any case, unionfs should probably cache the ref'ed upper/lower mount objects returned by vfs_register_upper_from_vp (as nullfs already does), because there are several cases outside of unmount() in which unionfs directly accesses ump->um_[lower|upper]vp->v_mount which aren't likely to be safe in the presence of a concurrent (recursive) forced unmount.
Comment 3 Karlo Miličević 2024-01-20 14:45:26 UTC
I tested the suggested patch on my system and everything seems to work correctly.
Comment 4 commit-hook freebsd_committer freebsd_triage 2024-02-18 15:15:50 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=cc3ec9f7597882d36ee487fd436d1b90bed0ebfd

commit cc3ec9f7597882d36ee487fd436d1b90bed0ebfd
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2023-12-22 20:13:35 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2024-02-18 15:14:05 +0000

    unionfs: cache upper/lower mount objects

    Store the upper/lower FS mount objects in unionfs per-mount data and
    use these instead of the v_mount field of the upper/lower root
    vnodes.  As described in the referenced PR, it is unsafe to access this
    field on the unionfs unmount path as ZFS rollback may have obliterated
    the v_mount field of the upper or lower root vnode.  Use these stored
    objects to slightly simplify other code that needs access to the
    upper/lower mount objects as well.

    PR:             275870
    Reported by:    Karlo Miličević <karlo98.m@gmail.com>
    Tested by:      Karlo Miličević <karlo98.m@gmail.com>
    Reviewed by:    kib (prior version), olce
    MFC after:      2 weeks
    Differential Revision: https://reviews.freebsd.org/D43815

 sys/fs/unionfs/union.h        |  2 ++
 sys/fs/unionfs/union_vfsops.c | 37 ++++++++++++++++++++-----------------
 sys/fs/unionfs/union_vnops.c  |  4 ++--
 3 files changed, 24 insertions(+), 19 deletions(-)
Comment 5 commit-hook freebsd_committer freebsd_triage 2024-03-04 18:51:58 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=5e806288f0c702e3f35efcf4972a97f0cf7b5676

commit 5e806288f0c702e3f35efcf4972a97f0cf7b5676
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2023-12-22 20:13:35 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2024-03-04 18:31:49 +0000

    unionfs: cache upper/lower mount objects

    Store the upper/lower FS mount objects in unionfs per-mount data and
    use these instead of the v_mount field of the upper/lower root
    vnodes.  As described in the referenced PR, it is unsafe to access this
    field on the unionfs unmount path as ZFS rollback may have obliterated
    the v_mount field of the upper or lower root vnode.  Use these stored
    objects to slightly simplify other code that needs access to the
    upper/lower mount objects as well.

    PR:             275870
    Reported by:    Karlo Miličević <karlo98.m@gmail.com>
    Tested by:      Karlo Miličević <karlo98.m@gmail.com>
    Reviewed by:    kib (prior version), olce
    Differential Revision: https://reviews.freebsd.org/D43815

    (cherry picked from commit cc3ec9f7597882d36ee487fd436d1b90bed0ebfd)

 sys/fs/unionfs/union.h        |  2 ++
 sys/fs/unionfs/union_vfsops.c | 37 ++++++++++++++++++++-----------------
 sys/fs/unionfs/union_vnops.c  |  4 ++--
 3 files changed, 24 insertions(+), 19 deletions(-)