Wednesday | 28 FEB 2024
[ previous ]
[ next ]

FUSE Tutorial - 04 readdir - Slowly

Date: 2023-02-02

Now that we have a mount point and it actually looks like a real directory, we can now populate said directory. We're going to start by first adding some dummy data and then we will add in logic to show sqlite tables as directories!

The first step is to write our readdir hook:

int sfs_readdir(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
    printf("Calling readdir on: %s\n",path);

    filler(buffer, ".", NULL, 0);
    filler(buffer, "..", NULL, 0);
    filler(buffer, "test.txt", NULL, 0);
    return 0;

We're going to hardcode the files that should exist in our directory. This is just so we can get something on the screen.

The first two files we're going to create are the references to the current directory and the one above us. The last thing we'll do is add an entry called test.txt.

Now we add our hook to the ops:

static struct fuse_operations sfs_ops = {
    .getattr = sfs_getattr,
    .readdir = sfs_readdir,

Compile and run:

gcc -lfuse -D_FILE_OFFSET_BITS=64 sfs.c -o sfs
./sfs -f db.sqlite dir

And if we do ls -la dir/:

ls -la dir
total 0
drwxr-xr-x 2 nivethan nivethan 4096 Dec 31  1969 .
drwxr-xr-x 3 nivethan nivethan   96 Feb  2 22:54 ..
-rw-r--r-- 2 nivethan nivethan 4096 Dec 31  1969 test.txt

We have created 2 hidden files and a test.txt file. They don't really exist but our filesystem thinks they do, magical!

Let's look at the output of the fuse program:

Getting attributes for: /
Calling readdir on: /
Getting attributes for: /test.txt

Interesting! We are calling getattr on the base directory, maybe it's only by doing that we know its a legitimate directory. Then fuse can call readdir on it which will get a list of files and then it calls getattr on the file inside.

The 2 hidden links however don't seem to call getattr which is strange. I wonder if that is the case for all hidden links.

Now we know how to make something look like a file. What we need to do now is somehow get our sqlite tables to appear as directories inside of dir.

The high level plan we're going to follow is that we should be able to get a list of tables from sqlite and then we need to add them using the filler function. Inside our readdir function, we're going to get a list of tables from sqlite and with that we will have exactly what we want!

Before we do that however, we're going to take a detour to the land of sqlite and get that going!