.fsync = cifs_fsync,
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
-       .splice_read = generic_file_splice_read,
+       .splice_read = cifs_splice_read,
        .splice_write = iter_file_splice_write,
        .llseek = cifs_llseek,
        .unlocked_ioctl = cifs_ioctl,
        .fsync = cifs_strict_fsync,
        .flush = cifs_flush,
        .mmap = cifs_file_strict_mmap,
-       .splice_read = generic_file_splice_read,
+       .splice_read = cifs_splice_read,
        .splice_write = iter_file_splice_write,
        .llseek = cifs_llseek,
        .unlocked_ioctl = cifs_ioctl,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
        .mmap = cifs_file_mmap,
-       .splice_read = generic_file_splice_read,
+       .splice_read = direct_splice_read,
        .splice_write = iter_file_splice_write,
        .unlocked_ioctl  = cifs_ioctl,
        .copy_file_range = cifs_copy_file_range,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
-       .splice_read = generic_file_splice_read,
+       .splice_read = cifs_splice_read,
        .splice_write = iter_file_splice_write,
        .llseek = cifs_llseek,
        .unlocked_ioctl = cifs_ioctl,
        .fsync = cifs_strict_fsync,
        .flush = cifs_flush,
        .mmap = cifs_file_strict_mmap,
-       .splice_read = generic_file_splice_read,
+       .splice_read = cifs_splice_read,
        .splice_write = iter_file_splice_write,
        .llseek = cifs_llseek,
        .unlocked_ioctl = cifs_ioctl,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
        .mmap = cifs_file_mmap,
-       .splice_read = generic_file_splice_read,
+       .splice_read = direct_splice_read,
        .splice_write = iter_file_splice_write,
        .unlocked_ioctl  = cifs_ioctl,
        .copy_file_range = cifs_copy_file_range,
 
 extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
+extern ssize_t cifs_splice_read(struct file *in, loff_t *ppos,
+                               struct pipe_inode_info *pipe, size_t len,
+                               unsigned int flags);
 extern int cifs_flock(struct file *pfile, int cmd, struct file_lock *plock);
 extern int cifs_lock(struct file *, int, struct file_lock *);
 extern int cifs_fsync(struct file *, loff_t, loff_t, int);
 
        .launder_folio = cifs_launder_folio,
        .migrate_folio = filemap_migrate_folio,
 };
+
+/*
+ * Splice data from a file into a pipe.
+ */
+ssize_t cifs_splice_read(struct file *in, loff_t *ppos,
+                        struct pipe_inode_info *pipe, size_t len,
+                        unsigned int flags)
+{
+       if (unlikely(*ppos >= file_inode(in)->i_sb->s_maxbytes))
+               return 0;
+       if (unlikely(!len))
+               return 0;
+       if (in->f_flags & O_DIRECT)
+               return direct_splice_read(in, ppos, pipe, len, flags);
+       return filemap_splice_read(in, ppos, pipe, len, flags);
+}