[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <83D4F976-29F7-467A-BC04-50FB7688FF22@tuxera.com>
Date: Thu, 29 Sep 2016 11:53:21 +0000
From: Anton Altaparmakov <anton@...era.com>
To: Al Viro <viro@...iv.linux.org.uk>
CC: linux-fsdevel <linux-fsdevel@...r.kernel.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Race condition between iget_locked() and evict_inodes()
Hi Al,
I think there is a race condition between iget_locked() and evict_inodes().
evict_inodes() checks i_count and if zero proceeds to take i_lock then set I_FREEING and eventually disposes of the inode.
But a concurrent iget_locked() takes i_lock and then increments i_count.
Thus if the events happen in this order:
evict_inodes() iget_locked() in find_inode_fast()
atomic_read(&inode->i_count) -> 0 take i_lock
wait on i_lock __iget(inode); -> i_count now 1
set I_FREEING drop i_lock
evict() return inode to caller
The inode is now gone due to the evict() call whilst it is happily being used with an elevated i_count by the iget_locked() calling process. It seems to me like evict_inodes() should be checking i_count inside i_lock either as the only check or it should at least re-check it.
Please tell me what I am missing here. I assume there must be something providing exclusion and I am just too blind to see it but I thought it worth bringing to your attention in case it really is simply broken.
Best regards,
Anton
--
Anton Altaparmakov <anton at tuxera.com> (replace at with @)
Lead in File System Development, Tuxera Inc., http://www.tuxera.com/
Linux NTFS maintainer
Powered by blists - more mailing lists