3

Env: Linux Kernel 5.3; FS: ext4

When requesting stat(const char *pathname, struct stat *statbuf) how is the const char *pathname is checked for existence?

It is necessary since in case there is no such path stat returns -1 (ENOENT). Here is the program I was testing:

static const char *pathname = "/some/fancy/path/name";

int main(void){
    struct stat statbuf;
    unsigned long i = 0;
    int fd = -1;
    while(1){
        if((++i) % 2){
            fd = open(pathname, O_CREAT, 0644);
        }
        stat(pathname, &statbuf);
        if(i % 2){
            close(fd);
            unlink(pathname);
        }
    }
}

Every 2 iterations the file was deleted and re-created again on the next one. To inspect kernel call stack I used perf report:

enter image description here

The call stack does not meet my expectation. I expected ext4 calls under the vfs_statx in order to traverse ext4 internal data structures which would probably require disk I/O.

If it was cached in the inode or dentry cache how to flush it in order to inspect what ext4 calls would require stat(const char *pathname, struct stat *statbuf);?

UPD: Taking closer look at the implementation I found that it seems to be taken from dentry cache as specified in the link_path_walk

Some Name
  • 8,555
  • 5
  • 27
  • 77
  • 2
    Take a look at the `path_init` function located at `fs/namei.c`. This function does the checks if the path you are trying to pass starts from root `/` or from the CWD `AT_FDCWD`. Maybe this can give you some more clue. – campescassiano May 06 '20 at 02:51
  • But, your main goal here is to see what `ext4_*` functions are being called, is that correct? Actually I did not understand what you really need. – campescassiano May 06 '20 at 11:45

1 Answers1

4

If it was cached in the inode or dentry cache how to flush it in order to inspect what ext4 calls would require stat(const char *pathname, struct stat *statbuf);?

You should be able to do this through /proc/sys/vm/drop_caches (from Documentation/sysctl/vm.txt):

drop_caches

Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes.  Once dropped, their
memory becomes free.

To free pagecache:
  echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
  echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
  echo 3 > /proc/sys/vm/drop_caches

Basically just: echo 2 | sudo tee /proc/sys/vm/drop_caches.


As per the real question, in order to find how ext4 handles lookups, you can look at the inode_operations struct defined in fs/ext4/namei.c. More specifically, you are interested in the .lookup operation, which is ext4_lookup(). This function is called when doing lookups.

The call tree should be like this:

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • Nice. I also reached to the point of `i_op->lookup()`, but for some reason looked at [`ext4_file_inode_operations`](https://elixir.bootlin.com/linux/v5.3/source/fs/ext4/file.c#L529) which does not have `lookup` initialized. I just realized that `lookup` operation does not make sense for a regular file though. – Some Name May 06 '20 at 16:04