access to nanosecond in struct inode

Viewed 77

In linux kernel v4.19.3

In my module, I need to get the inode last modification time in nanosecondes and not in seconds, but it always returns 0.

struct timespec64 i_mtime;

for example in this code :

pr_info("nsec = %ld - sec = %lld\n",inode->i_mtime.tv_nsec,inode->i_mtime.tv_sec);

this code returns :

nsec = 0 - sec = 1593096577

Any idea ?

2 Answers

This, of course, may depend on a specific file system that your inode is located on. Also, there's that unlikely chance that the time was exactly a round number of seconds.

However, the most likely reason for the behaviour you're observing is that in some Linux file systems the nanosecond part of each time-related timespec structure in the inode structure is set to zero when the inode is created. So, for instance, if you are getting zero nanoseconds in the last-modified time stamp, it likely means that the file has not been modified since its creation.

This is a minimal kernel module that prints the modification time of a predefined file. It compiles and works on Ubuntu with kernel 4.15.0-101-generic. The module is intentionally not loaded into the kernel and exits after printing out the timestamp values.

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/namei.h>

#define S_NAME  "test.txt"

static int __init s_init(void)
{
        int ret;
        struct path path;

        ret = kern_path(S_NAME, LOOKUP_FOLLOW, &path);

        if (ret) {
                pr_info("File not found '%s'\n", S_NAME);
        } else {
                pr_info("nsec = %ld - sec = %ld\n",
                        path.dentry->d_inode->i_mtime.tv_nsec,
                        path.dentry->d_inode->i_mtime.tv_sec);
        }

        return -1;
}

module_init(s_init);

MODULE_LICENSE("GPL");

I found out the problem :

This custom FS I'm using, has the s_time_gran of the struct SB (superblock) set at 10⁹, which is a worse granularity available (one second).

I changed it to 1, and I got the nanoseconds.

Related