NVSL / linux-nova

NOVA is a log-structured file system designed for byte-addressable non-volatile memories, developed at the University of California, San Diego.
http://nvsl.ucsd.edu/index.php?path=projects/nova
Other
425 stars 118 forks source link

Possible crash consistency issue with rename + link #119

Closed hayley-leblanc closed 2 years ago

hayley-leblanc commented 3 years ago

Hi,

I believe NOVA may have a crash consistency bug that arises in a specific scenario involving rename and link operations. Suppose we perform the following set of operations on an empty NOVA file system in the default configuration:

creat bar
mkdir A
rename bar A/bar
link A/bar bar

If we crash during the link operation, it's possible for the linkpath bar to not be present, but for the target A/bar to have a link count of 2. I believe this should be considered a crash consistency bug, since it reveals intermediate state to the user after the crash, and NOVA is meant to update metadata atomically.

It should be possible to reproduce the bug by adding the line goto out; after the call to nova_append_link_change_entry() on line 393 in namei.c, mounting a fresh NOVA instance at /mnt/pmem, running the following commands:

touch /mnt/pmem/bar
mkdir /mnt/pmem/A
mv /mnt/pmem/bar /mnt/pmem/A/bar
ln /mnt/pmem/A/bar /mnt/pmem/bar

If you then unmount and remount the file system, /mnt/pmem/bar is not present, but stat-ing /mnt/pmem/A/bar gives the following output:

  File: /mnt/pmem/A/bar
  Size: 0           Blocks: 8          IO Block: 4096   regular empty file
Device: 10301h/66305d   Inode: 33          Links: 2
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-11-11 20:37:51.000000000 +0000
Modify: 2021-11-11 20:37:51.000000000 +0000
Change: 2021-11-11 20:38:46.000000000 +0000
 Birth: -

It seems that this issue may also have implications for other processes/threads trying to read the link concurrently with the the process creating the link; with the simulated crash using goto out, if you stat /mnt/pmem/A/bar after the link, the link count has been increased but /mnt/pmem/bar is not present. This part of the issue also appears to be present even if the rename operation does not take place, but it seems that without the rename operation in the workload, the problem is resolved during recovery and the link count is set correctly.

Unfortunately I don't know exactly what the cause of this issue is at the moment and I don't have a fix, but I'll submit a PR if I figure it out.

Andiry commented 2 years ago

The issue is nova_rename() will append a link change entry to the log. nova_link() after that, will modify the existing link change entry instead of appending a new one, because there is no snapshot taken. So, a crash after nova_append_link_change_entry() will update the link change entry's links to 2.

Andiry commented 2 years ago

Fixed.