Как определить тип файла из модуля ядра? - PullRequest
0 голосов
/ 15 февраля 2019

Есть ли что-то вроде struct dirent* -> d_type, содержащее DT_REG, DT_DIR, DT_SOCK и т. Д. Для структур ядра, например для struct file?Глядя на его поля, я ничего не могу найти для этой цели.

Может быть, кто-то знает, как readdir определяет d_type?Я смотрю на его реализацию здесь https://github.com/lattera/glibc/blob/master/dirent/readdir.c и не могу понять, что здесь происходит.

Ubuntu18.04, 4.15.0-45 версия ядра

1 Ответ

0 голосов
/ 15 февраля 2019

Поле struct inode i_mode - это битовое поле, которое можно проверить с помощью стандартных макросов S_ISDIR, S_ISREG, S_ISLNK и др. :

/*
 * 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;
       .
       .
       .

Пример его использования в коде ядра ext4 :

/*
 * 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);
}

Обратите внимание, что вам нужно быть очень осторожным при обходе таких структур ядра.Если вы не берете правильные блокировки, они могут измениться из-за нити, исследующей их.

...