diff --git a/kmod/src/Makefile.kernelcompat b/kmod/src/Makefile.kernelcompat index 9c8bd9cb..88b97f89 100644 --- a/kmod/src/Makefile.kernelcompat +++ b/kmod/src/Makefile.kernelcompat @@ -222,3 +222,13 @@ endif ifneq (,$(shell grep 'define timer_container_of' include/linux/timer.h)) ccflags-y += -DKC_TIMER_CONTAINER_OF endif + +# +# v6.4-rc1-4f80818b4a58c +# +# iomap needs iterator nofault support in the read/write paths. We can still +# use iomap for fiemap and llseek though. +# +ifneq (,$(shell grep 'copy_page_to_iter_nofault' include/linux/uio.h)) +ccflags-y += -DKC_USE_IOMAP_FOR_IO +endif diff --git a/kmod/src/data.c b/kmod/src/data.c index 0bf0e5c7..9b03e7e1 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -1173,6 +1173,7 @@ out: return ret; } +#ifdef KC_USE_IOMAP_FOR_IO static int scoutfs_fadvise(struct file *file, loff_t start, loff_t end, int advice) { struct inode *inode = file_inode(file); @@ -1203,6 +1204,7 @@ static int scoutfs_fadvise(struct file *file, loff_t start, loff_t end, int advi return ret; } +#endif /* * A special case of initializing a single large offline extent. This @@ -2122,7 +2124,9 @@ static vm_fault_t scoutfs_data_filemap_fault(struct vm_fault *vmf) loff_t pos; int err; vm_fault_t ret = VM_FAULT_SIGBUS; +#ifdef KC_USE_IOMAP_FOR_IO void *semlock; +#endif bool found_lock; pos = vmf->pgoff; @@ -2157,19 +2161,23 @@ retry: found_lock = true; } +#ifdef KC_USE_IOMAP_FOR_IO semlock = scoutfs_per_task_get(&si->pt_extent_sem); if (semlock == NULL) { down_read(&si->extent_sem); if (!scoutfs_per_task_add_excl(&si->pt_extent_sem, &pt_sem, &semlock)) WARN_ON_ONCE(true); } +#endif ret = filemap_fault(vmf); +#ifdef KC_USE_IOMAP_FOR_IO if (semlock == NULL) { up_read(&si->extent_sem); scoutfs_per_task_del(&si->pt_extent_sem, &pt_sem); } +#endif out: if (!found_lock) { @@ -2232,7 +2240,9 @@ const struct file_operations scoutfs_file_fops = { .fsync = scoutfs_file_fsync, .llseek = scoutfs_file_llseek, .fallocate = scoutfs_fallocate, +#ifdef KC_USE_IOMAP_FOR_IO .fadvise = scoutfs_fadvise, +#endif }; void scoutfs_data_init_btrees(struct super_block *sb, diff --git a/kmod/src/file.c b/kmod/src/file.c index 76825cdf..e7a5e4e8 100644 --- a/kmod/src/file.c +++ b/kmod/src/file.c @@ -34,6 +34,8 @@ #include "trans.h" #include "msg.h" +#ifdef KC_USE_IOMAP_FOR_IO + static int lock_for_iomap_read(struct inode *inode, bool nowait, struct scoutfs_per_task_entry *pt_extent_ent) { @@ -61,7 +63,6 @@ static void unlock_for_iomap_read(struct inode *inode, up_read(&si->extent_sem); } -#ifdef KC_USE_IOMAP_FOR_IO static bool scoutfs_should_use_dio(struct kiocb *iocb, struct iov_iter *iter) { /* Current offset must be aligned */ @@ -684,14 +685,10 @@ ssize_t scoutfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) struct super_block *sb = inode->i_sb; struct scoutfs_lock *scoutfs_inode_lock = NULL; SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_ent); - SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_extent_ent); DECLARE_DATA_WAIT(dw); - bool locked; int ret; retry: - locked = false; - /* protect checked extents from release */ inode_lock(inode); atomic_inc(&inode->i_dio_count); @@ -702,12 +699,6 @@ retry: if (ret) goto out; - ret = lock_for_iomap_read(inode, false, &pt_extent_ent); - if (ret) - return ret; - - locked = true; - if (scoutfs_per_task_add_excl(&si->pt_data_lock, &pt_ent, scoutfs_inode_lock)) { ret = scoutfs_data_wait_check(inode, iocb->ki_pos, iov_iter_count(to), SEF_OFFLINE, SCOUTFS_IOC_DWO_READ, &dw, scoutfs_inode_lock); @@ -720,11 +711,6 @@ retry: ret = generic_file_read_iter(iocb, to); out: - if (locked) { - unlock_for_iomap_read(inode, &pt_extent_ent); - locked = false; - } - inode_dio_end(inode); scoutfs_per_task_del(&si->pt_data_lock, &pt_ent); scoutfs_unlock(sb, scoutfs_inode_lock, SCOUTFS_LOCK_READ); diff --git a/kmod/src/iomap.c b/kmod/src/iomap.c index 1a1e5fe7..8ca1a140 100644 --- a/kmod/src/iomap.c +++ b/kmod/src/iomap.c @@ -124,6 +124,12 @@ static int scoutfs_iomap_begin_report(struct inode *inode, loff_t offset, loff_t return ret; } +const struct iomap_ops scoutfs_iomap_report_ops = { + .iomap_begin = scoutfs_iomap_begin_report, +}; + +#ifdef KC_USE_IOMAP_FOR_IO + static int scoutfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, unsigned int flags, struct iomap *iomap, struct iomap *srcmap) @@ -261,11 +267,8 @@ static int scoutfs_iomap_end(struct inode *inode, loff_t offset, loff_t length, return ret; } -const struct iomap_ops scoutfs_iomap_report_ops = { - .iomap_begin = scoutfs_iomap_begin_report, -}; - const struct iomap_ops scoutfs_iomap_ops = { .iomap_begin = scoutfs_iomap_begin, .iomap_end = scoutfs_iomap_end, }; +#endif