Skip to content

Commit

Permalink
Explain why zfs_dirty_inode need TXG_WAIT
Browse files Browse the repository at this point in the history
  • Loading branch information
Grady Wong committed Oct 13, 2018
1 parent 8e221f6 commit 81851db
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions module/zfs/zfs_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 81851db

Please sign in to comment.