[PATCH] bfs: fix rename over existing file leaving stale dirent

From: dayou5941

Date: Thu Jul 30 2026 - 02:01:06 EST


From: liyouhong <liyouhong@xxxxxxxxxx>

When renaming over an existing target, bfs_rename() finds the destination
dirent but never updates new_de->ino to the source inode. It only clears
the source dirent and drops the replaced inode's nlink.

VFS still reports success and the live mount looks correct because the
dentry cache is updated, but after remount the destination name still
points at the old inode (or a freed one), while the renamed file becomes
unreachable. This is silent data loss on a normal mv of one file over
another.

Point the existing destination dirent at the source inode and dirty the
destination directory, matching the bfs_add_entry() path used when the
target name does not yet exist.

Assisted-by: Cursor:Composer
Signed-off-by: liyouhong <liyouhong@xxxxxxxxxx>
---
fs/bfs/dir.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 5b40ab09a796..0badbd3527a2 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -245,6 +245,12 @@ static int bfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
old_inode->i_ino);
if (error)
goto end_rename;
+ } else {
+ new_de->ino = cpu_to_le16((u16)old_inode->i_ino);
+ mmb_mark_buffer_dirty(new_bh, &BFS_I(new_dir)->i_metadata_bhs);
+ inode_set_mtime_to_ts(new_dir,
+ inode_set_ctime_current(new_dir));
+ mark_inode_dirty(new_dir);
}
old_de->ino = 0;
inode_set_mtime_to_ts(old_dir, inode_set_ctime_current(old_dir));
--
2.25.1