seidelma · GitHub

System information

Type Version/Name
Distribution Name Red Hat Enterprise Linux
Distribution Version 7.5
Linux Kernel 3.10.0-862.el7
Architecture x86_64
ZFS Version 0.7.8-1
SPL Version 0.7.8-1

Describe the problem you're observing

ZFS is unable to enumerate directories on RHEL 7.5, due to changes Red Hat has made to the kernel with 3.10.0-862. Kernel 3.10.0-693.21.1 from RHEL 7.4 does not experience this issue.

Describe how to reproduce the problem

Install RHEL 7.5
Install ZFS

# zpool create test /dev/sdb
# ls -alhtr /test
ls: reading directory /test: Not a directory
total 0

Include any warning/errors/backtraces from the system logs

This issue is caused by backported changes Red Hat made to their 3.10.0-862.el7 kernel. The getdents() system call now calls iterate_dir() (in fs/readdir.c) which also requires that the file be opened with f_mode & FMODE_KABI_ITERATE. In relevant part:

int iterate_dir(struct file *file, struct dir_context *ctx)
{
        struct inode *inode = file_inode(file);
        int res = -ENOTDIR;
        if (!file->f_op ||
            (!file->f_op->readdir && !(file->f_mode & FMODE_KABI_ITERATE)))
                goto out;
...

ZFS, for its part, #defines out the readdir() file op in module/zfs/zpl_file.c since it detects that the kernel supports iterate():

const struct file_operations zpl_dir_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
#ifdef HAVE_VFS_ITERATE_SHARED
        .iterate_shared = zpl_iterate,
#elif defined(HAVE_VFS_ITERATE)
        .iterate        = zpl_iterate,
#else
        .readdir        = zpl_readdir,
#endif
        .fsync          = zpl_fsync,
        .unlocked_ioctl = zpl_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = zpl_compat_ioctl,
#endif
};

Downgrading to RHEL's kernel-3.10.0-693.21.1.el7 package fixes the issue.

Read the original on github.com ↗