xfs: fix unmount hang and memory leak on shutdown during quotaoff
authorBrian Foster <bfoster@redhat.com>
Mon, 16 Mar 2020 21:26:09 +0000 (14:26 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 18 Mar 2020 15:12:23 +0000 (08:12 -0700)
commit8a62714313391b9b2297d67c341b35edbf46c279
tree17f0605090cedfe4ec9ad3964216048ded50e6ee
parent854f82b1f6039a418b7d1407513f8640e05fd73f
xfs: fix unmount hang and memory leak on shutdown during quotaoff

AIL removal of the quotaoff start intent and free of both quotaoff
intents is currently limited to the ->iop_committed() handler of the
end intent. This executes when the end intent is committed to the
on-disk log and marks the completion of the operation. The problem
with this is it assumes the success of the operation. If a shutdown
or other error occurs during the quotaoff, it's possible for the
quotaoff task to exit without removing the start intent from the
AIL. This results in an unmount hang as the AIL cannot be emptied.
Further, no other codepath frees the intents and so this is also a
memory leak vector.

First, update the high level quotaoff error path to directly remove
and free the quotaoff start intent if it still exists in the AIL at
the time of the error. Next, update both of the start and end
quotaoff intents with an ->iop_release() callback to properly handle
transaction abort.

This means that If the quotaoff start transaction aborts, it frees
the start intent in the transaction commit path. If the filesystem
shuts down before the end transaction allocates, the quotaoff
sequence removes and frees the start intent. If the end transaction
aborts, it removes the start intent and frees both. This ensures
that a shutdown does not result in a hung unmount and that memory is
not leaked regardless of when a quotaoff error occurs.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/xfs_dquot_item.c
fs/xfs/xfs_qm_syscalls.c