[PATCH v1] fs: Move might_sleep() annotation to iput_final()
Mateusz Guzik
mjguzik at gmail.com
Wed Nov 5 19:50:52 UTC 2025
On Wed, Nov 5, 2025 at 8:38 PM Mickaël Salaün <mic at digikod.net> wrote:
>
> iput() don't directly call any sleepable code but mostly checks flags
> and decrement a reference counter before calling iput_final() and then
> evict().
>
> Some code might call iput() with guarantees that iput_final() will not
> be called. This is the case for Landlock's hook_sb_delete() where the
> inode counter must de decremented while holding it with another
> reference, see comment above the first iput() call.
>
> Move the new might_sleep() call from iput() to iput_final(). The
> alternative would be to manually decrement the counter without calling
> iput(), but it doesn't seem right.
>
This would mostly defeat the point of the original change.
Instead, if you have a consumer which *guarantees* this is not the
last reference, the vfs layer can provide a helper which acts
accordingly.
Something like this (untested):
diff --git a/fs/inode.c b/fs/inode.c
index 84f539497857..a3ece9b4b6ef 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -2011,6 +2011,15 @@ void iput(struct inode *inode)
}
EXPORT_SYMBOL(iput);
+void iput_not_last(struct inode *inode)
+{
+ VFS_BUG_ON_INODE(inode_state_read_once(inode) & I_CLEAR, inode);
+ VFS_BUG_ON_INODE(atomic_read(&inode->i_count) < 2, inode);
+
+ WARN_ON(atomic_sub_return(1, &inode->i_count) == 0);
+}
+EXPORT_SYMBOL(iput_not_last);
+
#ifdef CONFIG_BLOCK
/**
* bmap - find a block number in a file
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 41c855ef0594..8181a0d0e2ac 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2909,6 +2909,7 @@ extern int current_umask(void);
extern void ihold(struct inode * inode);
extern void iput(struct inode *);
+void iput_not_last(struct inode *);
int inode_update_timestamps(struct inode *inode, int flags);
int generic_update_time(struct inode *, int);
More information about the Linux-security-module-archive
mailing list