Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine file type from kernel module?

Is there something like struct dirent* -> d_type that contains DT_REG, DT_DIR, DT_SOCK and etc. for kernel structures, for example for struct file? Looking at its fields, I cant find anything for this purpose.

Maybe someone knows how readdir determines d_type? I am looking at its implementation here https://github.com/lattera/glibc/blob/master/dirent/readdir.c and I cant understand what is going here.

Ubuntu18.04, 4.15.0-45 kernel version

like image 664
sanyassh Avatar asked Apr 25 '26 23:04

sanyassh


1 Answers

The struct inode field i_mode is a bit-field that can be checked using the standard S_ISDIR, S_ISREG, S_ISLNK et al macros:

/*
 * Keep mostly read-only and often accessed (especially for
 * the RCU path lookup and 'stat' data) fields at the beginning
 * of the 'struct inode'
 */
struct inode {
    umode_t         i_mode;
    unsigned short      i_opflags;
    kuid_t          i_uid;
    kgid_t          i_gid;
       .
       .
       .

An example of its use in ext4 kernel code:

/*
 * Test whether an inode is a fast symlink.
 * A fast symlink has its symlink data stored in ext4_inode_info->i_data.
 */
int ext4_inode_is_fast_symlink(struct inode *inode)
{
    if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) {
        int ea_blocks = EXT4_I(inode)->i_file_acl ?
                EXT4_CLUSTER_SIZE(inode->i_sb) >> 9 : 0;

        if (ext4_has_inline_data(inode))
            return 0;

        return (S_ISLNK(inode->i_mode) && inode->i_blocks - ea_blocks == 0);
    }
    return S_ISLNK(inode->i_mode) && inode->i_size &&
           (inode->i_size < EXT4_N_BLOCKS * 4);
}

Note that you need to be really careful traversing such kernel structures. If you don't take the proper locks, they can change out from under the thread examining them.

like image 60
Andrew Henle Avatar answered Apr 27 '26 19:04

Andrew Henle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!