xfs: hold quota inode ILOCK_EXCL until the end of dqalloc
authorDarrick J. Wong <djwong@kernel.org>
Wed, 5 Jan 2022 19:13:57 +0000 (11:13 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 6 Jan 2022 18:43:30 +0000 (10:43 -0800)
commiteae44cb341ec49f993867b44398b13c6d28600dc
tree1f58356c7e532e38ecc1053e8b69f60b52469deb
parentf4901a182d33d05a3b7020e2af97c635f6c47959
xfs: hold quota inode ILOCK_EXCL until the end of dqalloc

Online fsck depends on callers holding ILOCK_EXCL from the time they
decide to update a block mapping until after they've updated the reverse
mapping records to guarantee the stability of both mapping records.
Unfortunately, the quota code drops ILOCK_EXCL at the first transaction
roll in the dquot allocation process, which breaks that assertion.  This
leads to sporadic failures in the online rmap repair code if the repair
code grabs the AGF after bmapi_write maps a new block into the quota
file's data fork but before it can finish the deferred rmap update.

Fix this by rewriting the function to hold the ILOCK until after the
transaction commit like all other bmap updates do, and get rid of the
dqread wrapper that does nothing but complicate the codebase.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/xfs_dquot.c