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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With