ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1
authorZhihao Cheng <chengzhihao1@huawei.com>
Tue, 11 Oct 2022 03:47:31 +0000 (11:47 +0800)
committerRichard Weinberger <richard@nod.at>
Thu, 2 Feb 2023 20:13:40 +0000 (21:13 +0100)
If target inode is a special file (eg. block/char device) with nlink
count greater than 1, the inode with ui->data will be re-written on
disk. However, UBIFS losts target inode's data_len while doing space
budget. Bad space budget may let make_reservation() return with -ENOSPC,
which could turn ubifs to read-only mode in do_writepage() process.

Fetch a reproducer in [Link].

Link: https://bugzilla.kernel.org/show_bug.cgi?id=216494
Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system")
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
fs/ubifs/dir.c

index 7a1dcd1..4509d9f 100644 (file)
@@ -1324,6 +1324,8 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (unlink) {
                ubifs_assert(c, inode_is_locked(new_inode));
 
+               /* Budget for old inode's data when its nlink > 1. */
+               req.dirtied_ino_d = ALIGN(ubifs_inode(new_inode)->data_len, 8);
                err = ubifs_purge_xattrs(new_inode);
                if (err)
                        return err;