From 102619e813a7a05b73c58ac709af8304476f0753 Mon Sep 17 00:00:00 2001 From: Grady Wong Date: Sat, 13 Oct 2018 10:41:54 +0800 Subject: [PATCH] Explain why zfs_dirty_inode need TXG_WAIT Signed-off-by: Grady Wong --- module/zfs/zfs_vnops.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index c183fd3d8036..a362e3b5bddf 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -4656,16 +4656,18 @@ zfs_dirty_inode(struct inode *ip, int flags) top: tx = dmu_tx_create(zfsvfs->z_os); - dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); zfs_sa_upgrade_txholds(tx, zp); - boolean_t waited = B_FALSE; - error = dmu_tx_assign(tx, - waited ? (TXG_NOTHROTTLE | TXG_WAIT) : TXG_NOWAIT); + /* + * Despite this function allows an error to be returned, it's called + * from zpl_dirty_inode() which is a Linux VFS callback functions + * (.dirty_inode) which must always succeed, so we have to assign a + * txg with TXG_NOTHROTTLE plus TX_WAIT. + */ + error = dmu_tx_assign(tx, TXG_NOTHROTTLE | TXG_WAIT); if (error) { - if (error == ERESTART && waited == B_FALSE) { - waited = B_TRUE; + if (error == ERESTART) { dmu_tx_wait(tx); dmu_tx_abort(tx); goto top;