From 81851db57ec1a1606d2bc0063959643b69233529 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 --- module/zfs/zfs_vnops.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index c183fd3d8036..34c72214958c 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -4633,6 +4633,7 @@ zfs_dirty_inode(struct inode *ip, int flags) sa_bulk_attr_t bulk[4]; int error = 0; int cnt = 0; + boolean_t waited = B_FALSE; if (zfs_is_readonly(zfsvfs) || dmu_objset_is_snapshot(zfsvfs->z_os)) return (0); @@ -4656,15 +4657,20 @@ 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; + /* + * 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 when the first TXG_NOWAIT + * call failed. + */ error = dmu_tx_assign(tx, waited ? (TXG_NOTHROTTLE | TXG_WAIT) : TXG_NOWAIT); if (error) { - if (error == ERESTART && waited == B_FALSE) { + if (error == ERESTART) { waited = B_TRUE; dmu_tx_wait(tx); dmu_tx_abort(tx);