]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fs: assert on ->i_count in iput_final()
authorMateusz Guzik <mjguzik@gmail.com>
Wed, 1 Oct 2025 01:00:10 +0000 (03:00 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 20 Oct 2025 18:22:25 +0000 (20:22 +0200)
Notably make sure the count is 0 after the return from ->drop_inode(),
provided we are going to drop.

Inspired by suspicious games played by f2fs.

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/inode.c

index ec9339024ac36e7ba893f7dcc0f55feb7efd2f91..fa82cb810af440f3ff52418ccfc796398e85f5bf 100644 (file)
@@ -1879,6 +1879,7 @@ static void iput_final(struct inode *inode)
        int drop;
 
        WARN_ON(inode->i_state & I_NEW);
+       VFS_BUG_ON_INODE(atomic_read(&inode->i_count) != 0, inode);
 
        if (op->drop_inode)
                drop = op->drop_inode(inode);
@@ -1893,6 +1894,12 @@ static void iput_final(struct inode *inode)
                return;
        }
 
+       /*
+        * Re-check ->i_count in case the ->drop_inode() hooks played games.
+        * Note we only execute this if the verdict was to drop the inode.
+        */
+       VFS_BUG_ON_INODE(atomic_read(&inode->i_count) != 0, inode);
+
        state = inode->i_state;
        if (!drop) {
                WRITE_ONCE(inode->i_state, state | I_WILL_FREE);