Re: [syzbot] possible deadlock in dquot_commit
From: Jan Kara
Date: Thu Aug 12 2021 - 09:55:40 EST
On Wed 11-08-21 12:12:32, Hillf Danton wrote:
> On Tue, 10 Aug 2021 11:21:42 +0200 Jan Kara wrote:
> >
> >I'm not quite sure what you are asking about but yes, dquot_acquire() grabs
>
> It is hard to understand the rooms in mutex for two lock owners.
>
> >dquot->dq_lock, then e.g. v2_write_dquot() acquires dqio_sem, then
> >ext4_map_blocks() acquires i_data_sem/2 (special lock subclass for quota
> >files).
> >
> >What is unexpected is the #0 trace where i_data_sem/2 is acquired
> >by ext4_map_blocks() called from ext4_write_begin(). That shows that
> >normal write(2) call was able to operate on quota file which is certainly
> >wrong.
>
> The change below can test your theory.
> >
> >My patch closed one path how this could happen and I'm puzzled how
> >else this could happen. I'll try to reproduce the issue (I've already tried
> >but so far failed) as see if I can find out more.
>
> Actually there is one check for quota file near 100 lines of code lower,
> and copy it to just before taking i_data_sem to avoid writing the file of
> wrong type.
>
> Now only for thoughts.
>
> +++ x/fs/ext4/inode.c
> @@ -616,6 +616,8 @@ found:
> if (!(flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN))
> return retval;
>
> + if (ext4_is_quota_file(inode))
> + return -EINVAL;
> /*
> * Here we clear m_flags because after allocating an new extent,
> * it will be set again.
This would be certainly wrong. ext4_map_blocks() is used for accessing and
allocating blocks for quota file. It is ext4_write_begin() that should not
be called for the quota file. I've run the reproducer here for couple of
hours but the problem didn't trigger for me. Strange.
Honza
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR