Skip to content
Snippets Groups Projects
Commit 509f0069 authored by Hugh Dickins's avatar Hugh Dickins Committed by Christian Brauner
Browse files

shmem: fix quota lock nesting in huge hole handling


i_pages lock nests inside i_lock, but shmem_charge() and shmem_uncharge()
were being called from THP splitting or collapsing while i_pages lock was
held, and now go on to call dquot_alloc_block_nodirty() which takes
i_lock to update i_blocks.

We may well want to take i_lock out of this path later, in the non-quota
case even if it's left in the quota case (or perhaps use i_lock instead
of shmem's info->lock throughout); but don't get into that at this time.

Move the shmem_charge() and shmem_uncharge() calls out from under i_pages
lock, accounting the full batch of holes in a single call.

Still pass the pages argument to shmem_uncharge(), but it happens now to
be unused: shmem_recalc_inode() is designed to account for clean pages
freed behind shmem's back, so it gets the accounting right by itself;
then the later call to shmem_inode_unacct_blocks() led to imbalance
(that WARN_ON(inode->i_blocks) in shmem_evict_inode()).

Reported-by: default avatar <syzbot+38ca19393fb3344f57e6@syzkaller.appspotmail.com>
Closes: https://lore.kernel.org/lkml/0000000000008e62f40600bfe080@google.com/


Reported-by: default avatar <syzbot+440ff8cca06ee7a1d4db@syzkaller.appspotmail.com>
Closes: https://lore.kernel.org/lkml/00000000000076a7840600bfb6e8@google.com/


Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Tested-by: default avatarCarlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: default avatarCarlos Maiolino <cmaiolino@redhat.com>
Message-Id: <20230725144510.253763-8-cem@kernel.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent de4c0e7c
No related branches found
No related tags found
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment