Messages in this thread | | | Subject | Re: [PATCH -next] ubifs: rename_whiteout: correct old_dir size computing | From | "libaokun (A)" <> | Date | Thu, 17 Mar 2022 10:31:57 +0800 |
| |
在 2022/3/17 6:00, Richard Weinberger 写道: > ----- Ursprüngliche Mail ----- >> Von: "libaokun" <libaokun1@huawei.com> >> An: "richard" <richard@nod.at>, "linux-mtd" <linux-mtd@lists.infradead.org>, "linux-kernel" >> <linux-kernel@vger.kernel.org> >> CC: "yukuai3" <yukuai3@huawei.com>, "chengzhihao1" <chengzhihao1@huawei.com>, "libaokun" <libaokun1@huawei.com> >> Gesendet: Donnerstag, 10. März 2022 09:32:57 >> Betreff: Re: [PATCH -next] ubifs: rename_whiteout: correct old_dir size computing >> A gentle ping, sorry for the noise. > I have to say sorry for the day. > Thanks for your patience with me. > Please don't feel bad about it. Glad to hear from you! Thanks for your kindly reply! >> 在 2022/2/15 12:07, Baokun Li 写道: >>> When renaming the whiteout file, the old whiteout file is not deleted. >>> Therefore, we add the old dentry size to the old dir like XFS. >>> Otherwise, an error may be reported due to `fscki->calc_sz != fscki->size` >>> in check_indes. >>> >>> Fixes: 9e0a1fff8db56ea ("ubifs: Implement RENAME_WHITEOUT") >>> Reported-by: Zhihao Cheng <chengzhihao1@huawei.com> >>> Signed-off-by: Baokun Li <libaokun1@huawei.com> >>> --- >>> fs/ubifs/dir.c | 3 +++ >>> 1 file changed, 3 insertions(+) >>> >>> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c >>> index ae082a0be2a3..86151889548e 100644 >>> --- a/fs/ubifs/dir.c >>> +++ b/fs/ubifs/dir.c >>> @@ -1402,6 +1402,9 @@ static int do_rename(struct inode *old_dir, struct dentry >>> *old_dentry, >>> iput(whiteout); >>> goto out_release; >>> } >>> + >>> + /* Add the old_dentry size to the old_dir size. */ >>> + old_sz -= CALC_DENT_SIZE(fname_len(&old_nm)); > So you basically reset old_sz back to 0? Yes, reset old_sz to 0 here. Since the old file remains in old_dir after whiteout_rename, nothing has changed, we just add new_sz to the new folder.
Here, old_sz is the value to be subtracted from old_dir->i_size, which is initialized to `CALC_DENT_SIZE(fname_len(&old_nm));` . In RENAME_WHITEOUT, because the old file is not deleted, we need to subtract old_dent_size from old_sz after RENAME_WHITEOUT is complete, that is, set old_sz to 0.
we can easily reproduce this problem with the following script: ```C // test_ubifs_whiteout.c #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/syscall.h> #include <linux/fs.h>
int main(int argc, char *argv[]) { system("touch /root/temp/file"); syscall(SYS_renameat2, AT_FDCWD, "/root/temp/file", AT_FDCWD, "/root/temp/target", RENAME_WHITEOUT); return 0; } ```
```shell #!/bin/bash set -e # ubifs_whiteout_reproducer.sh
TMP=/root/temp umount $TMP 2>/dev/null || true mkdir -p $TMP
modprobe -r ubifs 2>/dev/null || true for i in $(seq 0 1) do ubidetach -p /dev/mtd$i 2>/dev/null || true done modprobe -r ubi 2>/dev/null || true modprobe -r nandsim 2>/dev/null || true modprobe nandsim id_bytes="0xec,0xa1,0x00,0x15" modprobe ubi mtd="0,512" ubimkvol -N vol_a -m -n 0 /dev/ubi0 modprobe ubifs mount -t ubifs /dev/ubi0_0 $TMP
./test_ubifs_whiteout umount /dev/ubi0_0 echo 1 > /sys/kernel/debug/ubifs/chk_fs mount -t ubifs /dev/ubi0_0 $TMP ``` > Thanks, > //richard > .
-- With Best Regards, Baokun Li
| |