| From d08d34636d1384d5ddb141e0bb72afa591c12118 Mon Sep 17 00:00:00 2001 |
| From: Sam Shih <sam.shih@mediatek.com> |
| Date: Fri, 2 Jun 2023 13:06:22 +0800 |
| Subject: [PATCH] |
| [spi-and-storage][999-2380-fix-dirty-race-between-do_tmpfile.patch] |
| |
| --- |
| fs/ubifs/dir.c | 60 +++++++++++++++++++++++++------------------------- |
| 1 file changed, 30 insertions(+), 30 deletions(-) |
| |
| diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c |
| index 332c0b02a..97b231c43 100644 |
| --- a/fs/ubifs/dir.c |
| +++ b/fs/ubifs/dir.c |
| @@ -356,6 +356,32 @@ out_budg: |
| return err; |
| } |
| |
| +/** |
| + * lock_2_inodes - a wrapper for locking two UBIFS inodes. |
| + * @inode1: first inode |
| + * @inode2: second inode |
| + * |
| + * We do not implement any tricks to guarantee strict lock ordering, because |
| + * VFS has already done it for us on the @i_mutex. So this is just a simple |
| + * wrapper function. |
| + */ |
| +static void lock_2_inodes(struct inode *inode1, struct inode *inode2) |
| +{ |
| + mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); |
| + mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); |
| +} |
| + |
| +/** |
| + * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes. |
| + * @inode1: first inode |
| + * @inode2: second inode |
| + */ |
| +static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) |
| +{ |
| + mutex_unlock(&ubifs_inode(inode2)->ui_mutex); |
| + mutex_unlock(&ubifs_inode(inode1)->ui_mutex); |
| +} |
| + |
| static int do_tmpfile(struct inode *dir, struct dentry *dentry, |
| umode_t mode, struct inode **whiteout) |
| { |
| @@ -364,7 +390,7 @@ static int do_tmpfile(struct inode *dir, |
| struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
| .dirtied_ino = 1}; |
| struct ubifs_budget_req ino_req = { .dirtied_ino = 1 }; |
| - struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir); |
| + struct ubifs_inode *ui; |
| int err, instantiated = 0; |
| struct fscrypt_name nm; |
| |
| @@ -426,11 +452,11 @@ static int do_tmpfile(struct inode *dir, |
| instantiated = 1; |
| mutex_unlock(&ui->ui_mutex); |
| |
| - mutex_lock(&dir_ui->ui_mutex); |
| + lock_2_inodes(dir, inode); |
| err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0); |
| if (err) |
| goto out_cancel; |
| - mutex_unlock(&dir_ui->ui_mutex); |
| + unlock_2_inodes(dir, inode); |
| |
| ubifs_release_budget(c, &req); |
| fscrypt_free_filename(&nm); |
| @@ -438,7 +464,7 @@ static int do_tmpfile(struct inode *dir, |
| return 0; |
| |
| out_cancel: |
| - mutex_unlock(&dir_ui->ui_mutex); |
| + unlock_2_inodes(dir, inode); |
| out_inode: |
| make_bad_inode(inode); |
| if (!instantiated) |
| @@ -673,32 +699,6 @@ static int ubifs_dir_release(struct inod |
| return 0; |
| } |
| |
| -/** |
| - * lock_2_inodes - a wrapper for locking two UBIFS inodes. |
| - * @inode1: first inode |
| - * @inode2: second inode |
| - * |
| - * We do not implement any tricks to guarantee strict lock ordering, because |
| - * VFS has already done it for us on the @i_mutex. So this is just a simple |
| - * wrapper function. |
| - */ |
| -static void lock_2_inodes(struct inode *inode1, struct inode *inode2) |
| -{ |
| - mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); |
| - mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); |
| -} |
| - |
| -/** |
| - * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes. |
| - * @inode1: first inode |
| - * @inode2: second inode |
| - */ |
| -static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) |
| -{ |
| - mutex_unlock(&ubifs_inode(inode2)->ui_mutex); |
| - mutex_unlock(&ubifs_inode(inode1)->ui_mutex); |
| -} |
| - |
| static int ubifs_link(struct dentry *old_dentry, struct inode *dir, |
| struct dentry *dentry) |
| { |
| -- |
| 2.34.1 |
| |