diff --git a/sys/fs/tarfs/tarfs_subr.c b/sys/fs/tarfs/tarfs_subr.c --- a/sys/fs/tarfs/tarfs_subr.c +++ b/sys/fs/tarfs/tarfs_subr.c @@ -384,6 +384,18 @@ tmp = tnp->tmp; switch (tnp->type) { + case VREG: + if (tnp->other != NULL) + tarfs_free_node(tnp->other); + if (tnp->nlink-- > 1) + return; + break; + case VDIR: + if (tnp->parent != tmp->root) + tarfs_free_node(tnp->parent); + if (tnp->nlink-- > 1) + return; + break; case VLNK: if (tnp->link.name) free(tnp->link.name, M_TARFSNAME); diff --git a/sys/fs/tarfs/tarfs_vfsops.c b/sys/fs/tarfs/tarfs_vfsops.c --- a/sys/fs/tarfs/tarfs_vfsops.c +++ b/sys/fs/tarfs/tarfs_vfsops.c @@ -744,6 +744,7 @@ error = EINVAL; goto bad; } + tnp->other->nlink++; break; case TAR_TYPE_SYMLINK: if (link == NULL) { diff --git a/tests/sys/fs/tarfs/tarfs_test.sh b/tests/sys/fs/tarfs/tarfs_test.sh --- a/tests/sys/fs/tarfs/tarfs_test.sh +++ b/tests/sys/fs/tarfs/tarfs_test.sh @@ -59,6 +59,7 @@ atf_check_equal "$(stat -f%d,%i "${mnt}"/sparse_file)" "$(stat -L -f%d,%i "${mnt}"/short_link)" atf_check_equal "$(stat -f%d,%i "${mnt}"/sparse_file)" "$(stat -L -f%d,%i "${mnt}"/long_link)" atf_check_equal "$(sha256 -q "${mnt}"/sparse_file)" ${sum} + atf_check_equal "$(stat -f%l "${mnt}"/sparse_file)" 2 } tarfs_basic_cleanup() { umount "${mnt}" || true