mirror of
https://github.com/versity/scoutfs.git
synced 2026-07-20 15:02:21 +00:00
Kernel compatibility changes for iomap on EL8
Add KC_USE_IOMAP_FOR_IO and only build the iomap R/W pieces for EL9 and higher. We support iomap for fiemap and llseek on EL8. Signed-off-by: Chris Kirby <ckirby@versity.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
+9
-118
@@ -34,38 +34,8 @@
|
||||
#include "trans.h"
|
||||
#include "msg.h"
|
||||
|
||||
static int lock_for_iomap_read(struct inode *inode, bool nowait,
|
||||
struct scoutfs_per_task_entry *pt_extent_ent)
|
||||
{
|
||||
#if 0
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
|
||||
if (nowait) {
|
||||
if (!down_read_trylock(&si->extent_sem))
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
down_read(&si->extent_sem);
|
||||
}
|
||||
|
||||
if (!scoutfs_per_task_add_excl(&si->pt_extent_sem, pt_extent_ent, pt_extent_ent))
|
||||
WARN_ON_ONCE(true);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unlock_for_iomap_read(struct inode *inode,
|
||||
struct scoutfs_per_task_entry *pt_extent_ent)
|
||||
{
|
||||
#if 0
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
|
||||
scoutfs_per_task_del(&si->pt_extent_sem, pt_extent_ent);
|
||||
up_read(&si->extent_sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef KC_USE_IOMAP_FOR_IO
|
||||
|
||||
static bool scoutfs_should_use_dio(struct kiocb *iocb, struct iov_iter *iter)
|
||||
{
|
||||
/* Current offset must be aligned */
|
||||
@@ -139,11 +109,6 @@ retry:
|
||||
if (!scoutfs_per_task_add_excl(&si->pt_extent_sem, &pt_extent_ent,
|
||||
&pt_extent_ent))
|
||||
WARN_ON_ONCE(true);
|
||||
#if 0
|
||||
ret = lock_for_iomap_read(inode, false, &pt_extent_ent);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
locked = true;
|
||||
|
||||
pagefault_disable();
|
||||
@@ -157,9 +122,6 @@ retry:
|
||||
if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) {
|
||||
scoutfs_per_task_del(&si->pt_extent_sem, &pt_extent_ent);
|
||||
up_read(&si->extent_sem);
|
||||
#if 0
|
||||
unlock_for_iomap_read(inode, &pt_extent_ent);
|
||||
#endif
|
||||
locked = false;
|
||||
window_size -= fault_in_iov_iter_writeable(to, window_size);
|
||||
if (window_size != 0)
|
||||
@@ -168,12 +130,8 @@ retry:
|
||||
|
||||
out:
|
||||
if (locked) {
|
||||
#if 1
|
||||
scoutfs_per_task_del(&si->pt_extent_sem, &pt_extent_ent);
|
||||
up_read(&si->extent_sem);
|
||||
#else
|
||||
unlock_for_iomap_read(inode, &pt_extent_ent);
|
||||
#endif
|
||||
}
|
||||
|
||||
return read ? read : ret;
|
||||
@@ -183,12 +141,9 @@ static ssize_t scoutfs_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
|
||||
bool nowait)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file_inode(file);
|
||||
SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_extent_ent);
|
||||
size_t prev_count = 0;
|
||||
size_t window_size = 0;
|
||||
size_t read = 0;
|
||||
bool locked = false;
|
||||
ssize_t ret;
|
||||
|
||||
if (!scoutfs_should_use_dio(iocb, to)) {
|
||||
@@ -197,12 +152,6 @@ static ssize_t scoutfs_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
|
||||
}
|
||||
|
||||
retry:
|
||||
ret = lock_for_iomap_read(inode, nowait, &pt_extent_ent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
locked = true;
|
||||
|
||||
pagefault_disable();
|
||||
to->nofault = true;
|
||||
ret = iomap_dio_rw(iocb, to, &scoutfs_iomap_ops, NULL, IOMAP_DIO_PARTIAL, 0);
|
||||
@@ -210,22 +159,17 @@ retry:
|
||||
pagefault_enable();
|
||||
|
||||
if (ret <= 0 && ret != -EFAULT)
|
||||
goto out_unlock;
|
||||
goto out;
|
||||
if (ret > 0)
|
||||
read = ret;
|
||||
|
||||
if (should_fault_in_pages(to, iocb, &prev_count, &window_size)) {
|
||||
unlock_for_iomap_read(inode, &pt_extent_ent);
|
||||
locked = false;
|
||||
window_size -= fault_in_iov_iter_writeable(to, window_size);
|
||||
if (window_size != 0)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
if (locked)
|
||||
unlock_for_iomap_read(inode, &pt_extent_ent);
|
||||
|
||||
out:
|
||||
file_accessed(file);
|
||||
|
||||
if (ret < 0)
|
||||
@@ -317,16 +261,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to complete all of our locking before we get into the iomap iterator.
|
||||
* The lock hierarchy isn't well defined, and some paths reverse the ordering of
|
||||
* the inode index lock and the extent_sem because of how the get_block functions
|
||||
* are called. So we have to use trylocks and retry as needed, unless nonblocking
|
||||
* mode was requested.
|
||||
*/
|
||||
static int lock_for_iomap_write(struct inode *inode, struct list_head *ind_locks,
|
||||
struct scoutfs_per_task_entry *pt_inode_ent,
|
||||
struct scoutfs_per_task_entry *pt_extent_ent,
|
||||
struct scoutfs_lock *scoutfs_inode_lock,
|
||||
bool nowait)
|
||||
{
|
||||
@@ -349,28 +285,8 @@ static int lock_for_iomap_write(struct inode *inode, struct list_head *ind_locks
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!down_write_trylock(&si->extent_sem)) {
|
||||
scoutfs_release_trans(sb);
|
||||
scoutfs_inode_index_unlock(sb, ind_locks);
|
||||
if (nowait)
|
||||
return -EAGAIN;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
scoutfs_per_task_add_excl(&si->pt_inode_locks, pt_inode_ent, ind_locks);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* We need to assign a pointer value to the per-task var. Since this
|
||||
* one is just a marker that we hold the extent_sem, it can be anything
|
||||
* that's non-NULL. So just use the entry itself.
|
||||
*/
|
||||
scoutfs_per_task_add_excl(&si->pt_extent_sem, pt_extent_ent,
|
||||
pt_extent_ent);
|
||||
#endif
|
||||
|
||||
ret = scoutfs_dirty_inode_item(inode, scoutfs_inode_lock);
|
||||
|
||||
break;
|
||||
@@ -383,7 +299,6 @@ static void unlock_for_iomap_write(struct inode *inode,
|
||||
struct scoutfs_lock *scoutfs_inode_lock,
|
||||
struct list_head *ind_locks,
|
||||
struct scoutfs_per_task_entry *pt_inode_ent,
|
||||
struct scoutfs_per_task_entry *pt_extent_ent,
|
||||
size_t written)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
@@ -399,13 +314,6 @@ static void unlock_for_iomap_write(struct inode *inode,
|
||||
BUG_ON(!t);
|
||||
|
||||
scoutfs_inode_index_unlock(sb, ind_locks);
|
||||
|
||||
#if 0
|
||||
t = scoutfs_per_task_del(&si->pt_extent_sem, pt_extent_ent);
|
||||
BUG_ON(!t);
|
||||
|
||||
up_write(&si->extent_sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ssize_t scoutfs_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
|
||||
@@ -415,7 +323,6 @@ static ssize_t scoutfs_file_direct_write(struct kiocb *iocb, struct iov_iter *fr
|
||||
struct inode *inode = file_inode(file);
|
||||
bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
|
||||
SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_inode_ent);
|
||||
SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_extent_ent);
|
||||
LIST_HEAD(ind_locks);
|
||||
size_t prev_count = 0;
|
||||
size_t window_size = 0;
|
||||
@@ -429,7 +336,7 @@ static ssize_t scoutfs_file_direct_write(struct kiocb *iocb, struct iov_iter *fr
|
||||
}
|
||||
|
||||
retry:
|
||||
ret = lock_for_iomap_write(inode, &ind_locks, &pt_inode_ent, &pt_extent_ent,
|
||||
ret = lock_for_iomap_write(inode, &ind_locks, &pt_inode_ent,
|
||||
scoutfs_inode_lock, nowait);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@@ -466,7 +373,7 @@ retry:
|
||||
*/
|
||||
if (should_fault_in_pages(from, iocb, &prev_count, &window_size)) {
|
||||
unlock_for_iomap_write(inode, scoutfs_inode_lock, &ind_locks,
|
||||
&pt_inode_ent, &pt_extent_ent, written);
|
||||
&pt_inode_ent, written);
|
||||
locked = false;
|
||||
window_size -= fault_in_iov_iter_readable(from, window_size);
|
||||
if (window_size != 0)
|
||||
@@ -476,7 +383,7 @@ retry:
|
||||
out:
|
||||
if (locked) {
|
||||
unlock_for_iomap_write(inode, scoutfs_inode_lock, &ind_locks,
|
||||
&pt_inode_ent, &pt_extent_ent, written);
|
||||
&pt_inode_ent, written);
|
||||
}
|
||||
|
||||
return ret < 0 ? ret : written;
|
||||
@@ -488,7 +395,6 @@ static ssize_t scoutfs_file_buffered_write(struct kiocb *iocb, struct iov_iter *
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file_inode(file);
|
||||
SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_inode_ent);
|
||||
SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_extent_ent);
|
||||
LIST_HEAD(ind_locks);
|
||||
size_t prev_count = 0;
|
||||
size_t window_size = 0;
|
||||
@@ -514,7 +420,7 @@ retry:
|
||||
from->count = min(from->count, window_size);
|
||||
}
|
||||
|
||||
ret = lock_for_iomap_write(inode, &ind_locks, &pt_inode_ent, &pt_extent_ent,
|
||||
ret = lock_for_iomap_write(inode, &ind_locks, &pt_inode_ent,
|
||||
scoutfs_inode_lock, false);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@@ -539,7 +445,7 @@ retry:
|
||||
* try another pass.
|
||||
*/
|
||||
unlock_for_iomap_write(inode, scoutfs_inode_lock, &ind_locks,
|
||||
&pt_inode_ent, &pt_extent_ent, written);
|
||||
&pt_inode_ent, written);
|
||||
locked = false;
|
||||
goto retry;
|
||||
}
|
||||
@@ -547,7 +453,7 @@ retry:
|
||||
out:
|
||||
if (locked) {
|
||||
unlock_for_iomap_write(inode, scoutfs_inode_lock, &ind_locks,
|
||||
&pt_inode_ent, &pt_extent_ent, written);
|
||||
&pt_inode_ent, written);
|
||||
}
|
||||
|
||||
from->count = orig_count - written;
|
||||
@@ -698,14 +604,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);
|
||||
@@ -716,12 +618,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);
|
||||
@@ -734,11 +630,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);
|
||||
|
||||
@@ -148,9 +148,6 @@ static int scoutfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length
|
||||
struct iomap *srcmap)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
#if 0
|
||||
SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_extent_ent);
|
||||
#endif
|
||||
struct super_block *sb = inode->i_sb;
|
||||
const u64 ino = scoutfs_ino(inode);
|
||||
struct scoutfs_lock *data_lock = NULL;
|
||||
@@ -164,9 +161,6 @@ static int scoutfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length
|
||||
int ret = 0;
|
||||
|
||||
WARN_ON_ONCE(flags & ~KNOWN_FLAGS);
|
||||
#if 0
|
||||
WARN_ON_ONCE(!rwsem_is_locked(&si->extent_sem));
|
||||
#endif
|
||||
|
||||
iblock = offset >> SCOUTFS_BLOCK_SM_SHIFT;
|
||||
|
||||
@@ -216,21 +210,12 @@ static int scoutfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length
|
||||
if (ret == 0)
|
||||
iomap->flags |= IOMAP_F_NEW;
|
||||
} else {
|
||||
#if 0
|
||||
ret = lock_for_iomap_read(inode, nowait, &pt_extent_ent);
|
||||
if (ret)
|
||||
goto out;
|
||||
#endif
|
||||
down_read(&si->extent_sem);
|
||||
|
||||
ret = scoutfs_ext_next(sb, &data_ext_ops, &args, iblock, 1, &ext);
|
||||
|
||||
up_read(&si->extent_sem);
|
||||
|
||||
#if 0
|
||||
unlock_for_iomap_read(inode, &pt_extent_ent);
|
||||
#endif
|
||||
|
||||
if (ret == -ENOENT)
|
||||
ret = 0;
|
||||
|
||||
@@ -272,12 +257,6 @@ static int scoutfs_iomap_end(struct inode *inode, loff_t offset, loff_t length,
|
||||
data_lock = scoutfs_per_task_get(&si->pt_data_lock);
|
||||
BUG_ON(!data_lock);
|
||||
|
||||
#if 0
|
||||
ret = lock_for_iomap_write(inode, &inode_locks, &pt_inode_ent,
|
||||
&pt_extent_ent, data_lock, nowait);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
down_write(&si->extent_sem);
|
||||
|
||||
/* convert unwritten to written, could be staging */
|
||||
|
||||
Reference in New Issue
Block a user