diff options
author | Hugh Dickins <hughd@google.com> | 2023-08-04 08:46:11 +0300 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2023-08-09 10:15:41 +0300 |
commit | 3c1b7528d8969a8e89c77cd5eb867503152547b1 (patch) | |
tree | b7f9537285fda7be02a77fb7db264796f7e23b93 /fs/Kconfig.binfmt | |
parent | 2be4f05af71bb2a9958c5680c19e5a489636ff42 (diff) | |
download | linux-3c1b7528d8969a8e89c77cd5eb867503152547b1.tar.xz |
shmem: move spinlock into shmem_recalc_inode() to fix quota support
Commit "shmem: fix quota lock nesting in huge hole handling" was not so
good: Smatch caught shmem_recalc_inode()'s shmem_inode_unacct_blocks()
descending into quota_send_warning(): where blocking GFP_NOFS is used,
yet shmem_recalc_inode() is called holding the shmem inode's info->lock.
Yes, both __dquot_alloc_space() and __dquot_free_space() are commented
"This operation can block, but only after everything is updated" - when
calling flush_warnings() at the end - both its print_warning() and its
quota_send_warning() may block.
Rework shmem_recalc_inode() to take the shmem inode's info->lock inside,
and drop it before calling shmem_inode_unacct_blocks().
And why were the spin_locks disabling interrupts? That was just a relic
from when shmem_charge() and shmem_uncharge() were called while holding
i_pages xa_lock: stop disabling interrupts for info->lock now.
To help stop me from making the same mistake again, add a might_sleep()
into shmem_inode_acct_block() and shmem_inode_unacct_blocks(); and those
functions have grown, so let the compiler decide whether to inline them.
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/linux-fsdevel/ffd7ca34-7f2a-44ee-b05d-b54d920ce076@moroto.mountain/
Signed-off-by: Hugh Dickins <hughd@google.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Message-Id: <29f48045-2cb5-7db-ecf1-72462f1bef5@google.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/Kconfig.binfmt')
0 files changed, 0 insertions, 0 deletions