Re: [PATCH v11 1/5] fs: add iput_if_not_last() helper

From: Mateusz Guzik

Date: Tue Jun 30 2026 - 05:11:26 EST


On Mon, Jun 29, 2026 at 07:08:44PM +0800, Yun Zhou wrote:
> Add a helper that drops an inode reference only if the caller does not
> hold the last one. Returns true if the reference was dropped, false
> otherwise.
>
> This is useful for filesystems that need to release inode references
> in contexts where triggering final iput (and thus eviction) would be
> unsafe due to lock ordering constraints. The caller can check the
> return value and defer the final iput to a safe context.
>
> Unlike iput_not_last() which BUG_ON's if called with the last ref,
> this variant is designed to be called speculatively.
>
> Signed-off-by: Yun Zhou <yun.zhou@xxxxxxxxxxxxx>
> Suggested-by: Jan Kara <jack@xxxxxxx>
> Reviewed-by: Jan Kara <jack@xxxxxxx>
> ---
> include/linux/fs.h | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index d10897b3a1e3..04f0de78fa7a 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2413,6 +2413,19 @@ static inline void super_set_sysfs_name_generic(struct super_block *sb, const ch
> extern void ihold(struct inode * inode);
> extern void iput(struct inode *);
> void iput_not_last(struct inode *);
> +
> +/**
> + * iput_if_not_last - drop an inode reference only if it is not the last one
> + * @inode: inode to put
> + *
> + * Returns true if the reference was dropped, false if this was the last
> + * reference and the caller must arrange for final iput() in a safe context.
> + */
> +static inline bool __must_check iput_if_not_last(struct inode *inode)
> +{
> + return atomic_add_unless(&inode->i_count, -1, 1);
> +}
> +

This still could assert on the count, for example:
VFS_BUG_ON_INODE(inode_state_read_once(inode) & (I_FREEING | I_CLEAR), inode);
VFS_BUG_ON_INODE(atomic_read(&inode->i_count) < 1, inode);

> int inode_update_time(struct inode *inode, enum fs_update_time type,
> unsigned int flags);
> int generic_update_time(struct inode *inode, enum fs_update_time type,
> --
> 2.43.0
>