diff mbox series

[3/4] ubifs: Update directory size when creating whiteouts

Message ID 20210122212229.17072-4-richard@nod.at
State Changes Requested
Headers show
Series [1/4] ubifs: Correctly set inode size in ubifs_link() | expand

Commit Message

Richard Weinberger Jan. 22, 2021, 9:22 p.m. UTC
Although whiteouts are unlinked files they will get re-linked later,
therefore the size of the parent directory needs to be updated too.

Cc: stable@vger.kernel.org
Fixes: 9e0a1fff8db5 ("ubifs: Implement RENAME_WHITEOUT")
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 fs/ubifs/dir.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Zhihao Cheng Jan. 23, 2021, 2:45 a.m. UTC | #1
在 2021/1/23 5:22, Richard Weinberger 写道:
> Although whiteouts are unlinked files they will get re-linked later,
I just want to make sure, is this where the count is increased?
do_rename -> inc_nlink(whiteout)
> therefore the size of the parent directory needs to be updated too.
> 
> Cc: stable@vger.kernel.org
> Fixes: 9e0a1fff8db5 ("ubifs: Implement RENAME_WHITEOUT")
> Signed-off-by: Richard Weinberger <richard@nod.at>
> ---
>   fs/ubifs/dir.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> index 8a34e0118ee9..b5d523e5854f 100644
> --- a/fs/ubifs/dir.c
> +++ b/fs/ubifs/dir.c
> @@ -361,6 +361,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
>   	struct ubifs_budget_req ino_req = { .dirtied_ino = 1 };
>   	struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir);
>   	int err, instantiated = 0;
> +	int sz_change = 0;
>   	struct fscrypt_name nm;
>   
>   	/*
> @@ -411,6 +412,8 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
>   		mark_inode_dirty(inode);
>   		drop_nlink(inode);
>   		*whiteout = inode;
> +		sz_change = CALC_DENT_SIZE(fname_len(&nm));
> +		dir->i_size += sz_change;
>   	} else {
>   		d_tmpfile(dentry, inode);
>   	}
> @@ -430,6 +433,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
>   	return 0;
>   
>   out_cancel:
Does this need a judgment? Like this,
if (whiteout)
     dir->i_size -= sz_change;
> +	dir->i_size -= sz_change;
>   	mutex_unlock(&dir_ui->ui_mutex);
>   out_inode:
>   	make_bad_inode(inode);
>
Richard Weinberger Jan. 23, 2021, 10:05 a.m. UTC | #2
----- Ursprüngliche Mail -----
> Von: "chengzhihao1" <chengzhihao1@huawei.com>
> An: "richard" <richard@nod.at>, "linux-mtd" <linux-mtd@lists.infradead.org>
> CC: "david" <david@sigma-star.at>, "linux-kernel" <linux-kernel@vger.kernel.org>, "stable" <stable@vger.kernel.org>
> Gesendet: Samstag, 23. Januar 2021 03:45:15
> Betreff: Re: [PATCH 3/4] ubifs: Update directory size when creating whiteouts

> 在 2021/1/23 5:22, Richard Weinberger 写道:
>> Although whiteouts are unlinked files they will get re-linked later,
> I just want to make sure, is this where the count is increased?
> do_rename -> inc_nlink(whiteout)

Exactly. The logic is a little wicked, I agree.
Let me think again whether there isn't a better way to address 
the problem.

Thanks,
//richard

P.s: Thanks a lot for reviewing!
Zhihao Cheng Jan. 25, 2021, 1:05 a.m. UTC | #3
在 2021/1/23 10:45, Zhihao Cheng 写道:

>> @@ -430,6 +433,7 @@ static int do_tmpfile(struct inode *dir, struct 
>> dentry *dentry,
>>       return 0;
>>   out_cancel:
Still one question:
> Does this need a judgment? Like this,
> if (whiteout)
>      dir->i_size -= sz_change;

>> +    dir->i_size -= sz_change;
>>       mutex_unlock(&dir_ui->ui_mutex);
>>   out_inode:
>>       make_bad_inode(inode);
>>
> 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
Richard Weinberger Jan. 25, 2021, 7:55 a.m. UTC | #4
On Mon, Jan 25, 2021 at 2:12 AM Zhihao Cheng <chengzhihao1@huawei.com> wrote:
>
> 在 2021/1/23 10:45, Zhihao Cheng 写道:
>
> >> @@ -430,6 +433,7 @@ static int do_tmpfile(struct inode *dir, struct
> >> dentry *dentry,
> >>       return 0;
> >>   out_cancel:
> Still one question:
> > Does this need a judgment? Like this,

The idea was that in the !whiteout case, sz_change is always 0.
Zhihao Cheng Jan. 25, 2021, 9:31 a.m. UTC | #5
在 2021/1/25 15:55, Richard Weinberger 写道:

> 
> The idea was that in the !whiteout case, sz_change is always 0.
> 
Oh, sz_change was initialized to 0, I missed it.
Thanks.
diff mbox series

Patch

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 8a34e0118ee9..b5d523e5854f 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -361,6 +361,7 @@  static int do_tmpfile(struct inode *dir, struct dentry *dentry,
 	struct ubifs_budget_req ino_req = { .dirtied_ino = 1 };
 	struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir);
 	int err, instantiated = 0;
+	int sz_change = 0;
 	struct fscrypt_name nm;
 
 	/*
@@ -411,6 +412,8 @@  static int do_tmpfile(struct inode *dir, struct dentry *dentry,
 		mark_inode_dirty(inode);
 		drop_nlink(inode);
 		*whiteout = inode;
+		sz_change = CALC_DENT_SIZE(fname_len(&nm));
+		dir->i_size += sz_change;
 	} else {
 		d_tmpfile(dentry, inode);
 	}
@@ -430,6 +433,7 @@  static int do_tmpfile(struct inode *dir, struct dentry *dentry,
 	return 0;
 
 out_cancel:
+	dir->i_size -= sz_change;
 	mutex_unlock(&dir_ui->ui_mutex);
 out_inode:
 	make_bad_inode(inode);