linux-nova
linux-nova copied to clipboard
Incorrect inode number emitted from nova_readdir_fast
Issue
The inode number is incorrect when readdir.
Reproduce
The blow C code is used to read the directory and print out the d_ino.
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
void print_dirents(DIR * dir){
struct dirent *entry;
while ( (entry=readdir(dir)) != NULL ){
printf("%s, %ld\n", entry->d_name, entry->d_ino);
}
}
int main(int argc, char **argv){
if (argc != 2) {
printf("usgae: execuable [path]\n");
return 0;
}
char *dir_name = argv[1];
DIR *dir;
dir = opendir(dir_name);
print_dirents(dir);
closedir(dir);
return 0;
}
sudo insmod nova.ko
sudo mount -t NOVA -o init,dbgmask=255 /dev/pmem0 /mnt/pmem0
sudo mkdir /mnt/pmem/dir
# assuming the executable C code is a.out
./a.out /mnt/pmem0
# the output is:
# ., 1
# .., 33
# dir, 33
# The syslog shows the inode number for the `..` file and the `dir` entry is correct.
Reason
https://github.com/NVSL/linux-nova/blob/976a4d1f3d5282863b23aa834e02012167be6ee2/fs/nova/dir.c#L708-L713 https://github.com/NVSL/linux-nova/blob/976a4d1f3d5282863b23aa834e02012167be6ee2/fs/nova/dir.c#L728-L731
In the above code snippet, the inode number passed to dir_emit is incorrect. It should be prev_entryc->ino rather than ino. This explains why the .. file's inode is 33 and dir's inode is still 33.
Fix
Simply modify the ino as prev_entryc->ino as the below code shows.
// dir.c#L708-L713
if (prev_entry && !dir_emit(ctx, prev_entryc->name,
prev_entryc->name_len, prev_entryc->ino,
IF2DT(le16_to_cpu(prev_child_pi->i_mode)))) {
nova_dbgv("Here: pos %llu\n", ctx->pos);
return 0;
}
// dir.c#L728-L731
if (prev_entry && !dir_emit(ctx, prev_entryc->name,
prev_entryc->name_len, prev_entryc->ino,
IF2DT(le16_to_cpu(prev_child_pi->i_mode))))
return 0;