Panic upon unmounting zfs snapshot: "vput: negative ref cnt"
Richard Todd
rmtodd at ichotolot.servalan.com
Mon Dec 1 21:45:07 PST 2008
Richard Todd <rmtodd at ichotolot.servalan.com> writes:
> I'm running -CURRENT as of this Thursday, and discovered the following panic
> upon doing the fairly straightforward steps of making a snapshot, mounting
> it, doing some activity reading from the snapshot, and unmounting it --
> the exact sequence of commands was something like
> zfs snapshot u1 at foosnap
> mount -r -t zfs u1 at foosnap /mnt
> ls -lR /mnt
> umount /mnt
>
> Got a crash dump, gdb info follows. Note that the offending vp seems to be
> the vnode for the mount point that the snapshot was mounted on.
A bit more exploration and littering the unmount code with vprint()s and I
think I've narrowed down the problem to the following bit of code near the
end of zfs_umount in
/usr/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
if (zfsvfs->z_issnap) {
vnode_t *svp = vfsp->mnt_vnodecovered;
ASSERT(svp->v_count == 2);
VN_RELE(svp);
}
The above code seems to assume that the ZFS snapshot being unmounted was
mounted through the .zfs/snapshot pseudo-directory mechanism; apparently
on mount the underlying vnode (for the .zfs/snapshot/xxx) has an extra
reference added, so a VN_RELE needs to be done. But if the mount of the
snapshot was done manually (via mount -t zfs), then the underlying vnode
*doesn't* have the extra reference, so the VN_RELE here means that the later
vput() in dounmount will panic.
The above code should be probably smarter and test whether
vfsp->mnt_vnodecovered points to the .zfs/snapshot pseudodirectory or not;
unfortunately, I'm not sure how to do that. Since I usually mount snapshots
by hand instead of using the .zfs/snapshot mechanism, for my purposes just
commenting out the above chunk of code solves my problem for the time being.
More information about the freebsd-current
mailing list