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

Ignored NEXT_PAGE flag in the function nova_background_clean_snapshot_list #138

Closed iaoing closed 2 years ago

iaoing commented 2 years ago

Issue

In the function nova_background_clean_snapshot_list, some situations will arise "unknown type" error. For example, after deletion some snapshots, if the snapshot list looks like below:

| entry | entry | ... | NEXT_PAGE | page_addr | ----> | NEXT_PAGE | ... | page_addr | ----> | entry | tail | ... |
|<------------------ page 1 ----------------->|       |<--------- page  2 --------->|       |<----- page 3 ----->|

The process will ignore the NEXT_PAGE flag in the first entry of the second page, and keep going to access invalid entries in the second page.

Reproduce

mount -t NOVA -o init,dbgmask=255 /dev/pmem0 /mnt/pmem0
# create snapshot_0
touch /mnt/pmem0/file.1
echo 1 > /proc/fs/NOVA/pmem0/create_snapshot
# create snapshot_1
touch /mnt/pmem0/file.2
echo 1 > /proc/fs/NOVA/pmem0/create_snapshot
# create snapshot_2
rm /mnt/pmem0/file.1
echo 1 > /proc/fs/NOVA/pmem0/create_snapshot
# create snapshot_3
rm /mnt/pmem0/file.2
echo 1 > /proc/fs/NOVA/pmem0/create_snapshot

# delete snapshot 0 and 1 to form the linked snapshot list like the above figure shows
echo 1 > /proc/fs/NOVA/pmem0/delete_snapshot
echo 2 > /proc/fs/NOVA/pmem0/delete_snapshot

# dmesg will show the error message
dmesg

Reason

https://github.com/NVSL/linux-nova/blob/b817ca322e6fc61f532174e7effc4b6c81528e3f/fs/nova/snapshot.c#L217-L253 At Line 220, curr_p is the first entry of a page. The function checks if this entry is the tail or it has a larger epoch id at Line 221 and 224. Then, it gets the type of this entry and switch case it. So, if the type is "NEXT_PAGE", it will cause the error at Line 247.

Similar issues at Line 132 - 137 in the function nova_delete_snapshot_list_entries. https://github.com/NVSL/linux-nova/blob/b817ca322e6fc61f532174e7effc4b6c81528e3f/fs/nova/snapshot.c#L132-L137

Fix

If go the next page, just continue the while loop. The tail and the epoch id conditions will be checked by the while loop.

/* for both Line 132 - 137 in function nova_delete_snapshot_list_entries */
if (goto_next_list_page(sb, curr_p)) {
    curr_p = next_list_page(curr_p);
    continue;
}
/* for Line 217 - 226 in nova_background_clean_snapshot_list */
if (goto_next_list_page(sb, curr_p)) {
    curr_p = next_list_page(curr_p);
    curr_page = (struct nova_inode_log_page *)curr_p;
    continue;
}
Andiry commented 2 years ago

Thanks. Please send a PR and I am happy to apply.

iaoing commented 2 years ago

Since this issue needs to modify the same file of issue #136. I will send the PR after that one is accepted to avoid trouble.

Andiry commented 2 years ago

Thanks. The previous PR is merged.