Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashing during unlinking can lead to wrong st_nlink #125

Open
pcworld opened this issue Nov 13, 2021 · 2 comments
Open

Crashing during unlinking can lead to wrong st_nlink #125

pcworld opened this issue Nov 13, 2021 · 2 comments

Comments

@pcworld
Copy link
Contributor

pcworld commented Nov 13, 2021

When creating a file with 2 links, then unlinking it and crashing during memcpy_to_pmem_nocache in nova_update_alter_entry (<- nova_inplace_update_log_entry <- nova_inplace_update_dentry <- nova_remove_dentry <- nova_unlink), recovering from that crash state results in a single file with st_nlink reported as 2.
I am not completely sure whether this is actually a bug or implementation detail.
It seems worth investigating whether this can lead to followup bugs, like unlinking the last actually existing file not freeing the inode or similar.

@Andiry
Copy link
Contributor

Andiry commented Nov 23, 2021

Can you post the reproduce steps? Thanks.

@iaoing
Copy link
Contributor

iaoing commented Jan 18, 2024

Reproduce

linux-nova/fs/nova/namei.c

Lines 435 to 440 in 976a4d1

update_dir.tail = 0;
update_dir.alter_tail = 0;
retval = nova_remove_dentry(dentry, 0, &update_dir, epoch_id, false);
if (retval)
goto out;

Add return 0 after remove the dentry to simulate a crash.

update_dir.tail = 0;
update_dir.alter_tail = 0;
retval = nova_remove_dentry(dentry, 0, &update_dir, epoch_id, false);
if (retval)
    goto out;

# simulate a crash
return 0;
# rebuild after the modification
insmod nova.ko metadata_csum=1 data_csum=1 data_parity=1 dram_struct_csum=1
mount -t NOVA -o init,data_cow,dbgmask=255 /dev/pmem0 /mnt/pmem0
touch /mnt/pmem0/foo
ln /mnt/pmem0/foo /mnt/pmem0/bar
# stat will show both foo and bar have two links
stat /mnt/pmem0/foo
stat /mnt/pmem0/bar
# unlink function will trigger the modification in the source code, simulating a crash
unlink /mnt/pmem0/foo
# store the crash image
cat /dev/pmem0 > image
# umount and remount the crash image
umount /mnt/pmem0
cat image > /dev/pmem0
sudo mount -t NOVA -o data_cow,dbgmask=255 /dev/pmem0 /mnt/pmem0
# stat will show foo is gone, but the link count of bar is still 2
stat /mnt/pmem0/foo
stat /mnt/pmem0/bar

Reason

The removal of the dentry is conducted in-place, before updating the link count. Thus, if a crash occurs after the removal, we cannot see the dentry but the link is outdated.

Fix

Disable the in-place update option for unlink.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants