diff --git a/kmod/src/Makefile.kernelcompat b/kmod/src/Makefile.kernelcompat index 6393ac1f..1ea7a805 100644 --- a/kmod/src/Makefile.kernelcompat +++ b/kmod/src/Makefile.kernelcompat @@ -213,3 +213,15 @@ endif ifneq (,$(shell grep 'extern ssize_t generic_file_buffered_write' include/linux/fs.h)) ccflags-y += -DKC_GENERIC_FILE_BUFFERED_WRITE=1 endif + +# +# v5.7-438-g8151b4c8bee4 +# +# struct address_space_operations switches away from .readpages to .readahead +# +# RHEL has backported this feature all the way to RHEL8, as part of RHEL_KABI, +# which means we need to detect this very precisely +# +ifneq (,$(shell grep 'readahead.*struct readahead_control' include/linux/fs.h)) +ccflags-y += -DKC_FILE_AOPS_READAHEAD +endif diff --git a/kmod/src/data.c b/kmod/src/data.c index a51ee67b..987f90a1 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -729,6 +729,7 @@ static int scoutfs_readpage(struct file *file, struct page *page) return ret; } +#ifndef KC_FILE_AOPS_READAHEAD /* * This is used for opportunistic read-ahead which can throw the pages * away if it needs to. If the caller didn't deal with offline extents @@ -775,6 +776,29 @@ out: BUG_ON(!list_empty(pages)); return ret; } +#else +static void scoutfs_readahead(struct readahead_control *rac) +{ + struct inode *inode = rac->file->f_inode; + struct super_block *sb = inode->i_sb; + struct scoutfs_lock *inode_lock = NULL; + int ret; + + ret = scoutfs_lock_inode(sb, SCOUTFS_LOCK_READ, + SCOUTFS_LKF_REFRESH_INODE, inode, &inode_lock); + if (ret) + return; + + ret = scoutfs_data_wait_check(inode, readahead_pos(rac), + readahead_length(rac), SEF_OFFLINE, + SCOUTFS_IOC_DWO_READ, NULL, + inode_lock); + if (ret == 0) + mpage_readahead(rac, scoutfs_get_block_read); + + scoutfs_unlock(sb, inode_lock, SCOUTFS_LOCK_READ); +} +#endif static int scoutfs_writepage(struct page *page, struct writeback_control *wbc) { @@ -1873,7 +1897,11 @@ int scoutfs_data_waiting(struct super_block *sb, u64 ino, u64 iblock, const struct address_space_operations scoutfs_file_aops = { .readpage = scoutfs_readpage, +#ifndef KC_FILE_AOPS_READAHEAD .readpages = scoutfs_readpages, +#else + .readahead = scoutfs_readahead, +#endif .writepage = scoutfs_writepage, .writepages = scoutfs_writepages, .write_begin = scoutfs_write_begin,