From 2efb7660b58aed735469192436c1e8ada5561d18 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 22 Aug 2018 16:32:53 +0000 Subject: [PATCH] Add dmu_tx_assign() error handling in zfs_unlinked_drain(). The error handling got lost during r334810, while according to the report error there may happen in case of dataset being over quota. In such case just leave the node in the unlinked list to be freed sometimes later. PR: 229887 Sponsored by: iXsystems, Inc. --- .../opensolaris/uts/common/fs/zfs/zfs_dir.c | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c index 66c2713e6312..775697867f62 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c @@ -318,20 +318,27 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs) continue; vn_lock(ZTOV(zp), LK_EXCLUSIVE | LK_RETRY); - zp->z_unlinked = B_TRUE; #if defined(__FreeBSD__) /* * Due to changes in zfs_rmnode we need to make sure the * link count is set to zero here. */ - zp->z_links = 0; - tx = dmu_tx_create(zfsvfs->z_os); - dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); - VERIFY(0 == dmu_tx_assign(tx, TXG_WAIT)); - VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs), - &zp->z_links, sizeof (zp->z_links), tx)); - dmu_tx_commit(tx); + if (zp->z_links != 0) { + tx = dmu_tx_create(zfsvfs->z_os); + dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); + error = dmu_tx_assign(tx, TXG_WAIT); + if (error != 0) { + dmu_tx_abort(tx); + vput(ZTOV(zp)); + continue; + } + zp->z_links = 0; + VERIFY0(sa_update(zp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs), + &zp->z_links, sizeof (zp->z_links), tx)); + dmu_tx_commit(tx); + } #endif + zp->z_unlinked = B_TRUE; vput(ZTOV(zp)); } zap_cursor_fini(&zc);