Commit 8f04e1be authored by Martin Brandenburg's avatar Martin Brandenburg Committed by Mike Marshall

orangefs: add orangefs_revalidate_mapping

This is modeled after NFS, except our method is different.  We use a
simple timer to determine whether to invalidate the page cache.  This
is bound to perform.

This addes a sysfs parameter cache_timeout_msecs which controls the time
between page cache invalidations.
Signed-off-by: default avatarMartin Brandenburg <martin@omnibond.com>
Signed-off-by: default avatarMike Marshall <hubcap@omnibond.com>
parent c472ebc2
......@@ -241,18 +241,78 @@ ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
return ret;
}
int orangefs_revalidate_mapping(struct inode *inode)
{
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
struct address_space *mapping = inode->i_mapping;
unsigned long *bitlock = &orangefs_inode->bitlock;
int ret;
while (1) {
ret = wait_on_bit(bitlock, 1, TASK_KILLABLE);
if (ret)
return ret;
spin_lock(&inode->i_lock);
if (test_bit(1, bitlock)) {
spin_unlock(&inode->i_lock);
continue;
}
if (!time_before(jiffies, orangefs_inode->mapping_time))
break;
spin_unlock(&inode->i_lock);
return 0;
}
set_bit(1, bitlock);
smp_wmb();
spin_unlock(&inode->i_lock);
unmap_mapping_range(mapping, 0, 0, 0);
ret = filemap_write_and_wait(mapping);
if (!ret)
ret = invalidate_inode_pages2(mapping);
orangefs_inode->mapping_time = jiffies +
orangefs_cache_timeout_msecs*HZ/1000;
clear_bit(1, bitlock);
smp_mb__after_atomic();
wake_up_bit(bitlock, 1);
return ret;
}
static ssize_t orangefs_file_read_iter(struct kiocb *iocb,
struct iov_iter *iter)
{
int ret;
orangefs_stats.reads++;
return generic_file_read_iter(iocb, iter);
down_read(&file_inode(iocb->ki_filp)->i_rwsem);
ret = orangefs_revalidate_mapping(file_inode(iocb->ki_filp));
if (ret)
goto out;
ret = generic_file_read_iter(iocb, iter);
out:
up_read(&file_inode(iocb->ki_filp)->i_rwsem);
return ret;
}
static ssize_t orangefs_file_write_iter(struct kiocb *iocb,
struct iov_iter *iter)
{
int ret;
orangefs_stats.writes++;
return generic_file_write_iter(iocb, iter);
if (iocb->ki_pos > i_size_read(file_inode(iocb->ki_filp))) {
ret = orangefs_revalidate_mapping(file_inode(iocb->ki_filp));
if (ret)
return ret;
}
ret = generic_file_write_iter(iocb, iter);
return ret;
}
/*
......@@ -341,6 +401,12 @@ static const struct vm_operations_struct orangefs_file_vm_ops = {
*/
static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
int ret;
ret = orangefs_revalidate_mapping(file_inode(file));
if (ret)
return ret;
gossip_debug(GOSSIP_FILE_DEBUG,
"orangefs_file_mmap: called on %s\n",
(file ?
......
This diff is collapsed.
......@@ -193,9 +193,11 @@ struct orangefs_inode_s {
sector_t last_failed_block_index_read;
unsigned long getattr_time;
unsigned long mapping_time;
int attr_valid;
kuid_t attr_uid;
kgid_t attr_gid;
unsigned long bitlock;
DECLARE_HASHTABLE(xattr_cache, 4);
};
......@@ -390,6 +392,7 @@ bool __is_daemon_in_service(void);
/*
* defined in file.c
*/
int orangefs_revalidate_mapping(struct inode *);
ssize_t wait_for_direct_io(enum ORANGEFS_io_type, struct inode *, loff_t *,
struct iov_iter *, size_t, loff_t, struct orangefs_write_range *);
ssize_t do_readv_writev(enum ORANGEFS_io_type, struct file *, loff_t *,
......@@ -427,6 +430,7 @@ int orangefs_normalize_to_errno(__s32 error_code);
extern struct mutex orangefs_request_mutex;
extern int op_timeout_secs;
extern int slot_timeout_secs;
extern int orangefs_cache_timeout_msecs;
extern int orangefs_dcache_timeout_msecs;
extern int orangefs_getattr_timeout_msecs;
extern struct list_head orangefs_superblocks;
......
......@@ -30,6 +30,7 @@ static ulong module_parm_debug_mask;
__u64 orangefs_gossip_debug_mask;
int op_timeout_secs = ORANGEFS_DEFAULT_OP_TIMEOUT_SECS;
int slot_timeout_secs = ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS;
int orangefs_cache_timeout_msecs = 50;
int orangefs_dcache_timeout_msecs = 50;
int orangefs_getattr_timeout_msecs = 50;
......
......@@ -62,6 +62,14 @@
* Slots are requested and waited for,
* the wait times out after slot_timeout_secs.
*
* What: /sys/fs/orangefs/cache_timeout_msecs
* Date: Mar 2018
* Contact: Martin Brandenburg <martin@omnibond.com>
* Description:
* Time in milliseconds between which
* orangefs_revalidate_mapping will invalidate the page
* cache.
*
* What: /sys/fs/orangefs/dcache_timeout_msecs
* Date: Jul 2016
* Contact: Martin Brandenburg <martin@omnibond.com>
......@@ -221,6 +229,13 @@ static ssize_t sysfs_int_show(struct kobject *kobj,
"%d\n",
slot_timeout_secs);
goto out;
} else if (!strcmp(attr->attr.name,
"cache_timeout_msecs")) {
rc = scnprintf(buf,
PAGE_SIZE,
"%d\n",
orangefs_cache_timeout_msecs);
goto out;
} else if (!strcmp(attr->attr.name,
"dcache_timeout_msecs")) {
rc = scnprintf(buf,
......@@ -277,6 +292,9 @@ static ssize_t sysfs_int_store(struct kobject *kobj,
} else if (!strcmp(attr->attr.name, "slot_timeout_secs")) {
rc = kstrtoint(buf, 0, &slot_timeout_secs);
goto out;
} else if (!strcmp(attr->attr.name, "cache_timeout_msecs")) {
rc = kstrtoint(buf, 0, &orangefs_cache_timeout_msecs);
goto out;
} else if (!strcmp(attr->attr.name, "dcache_timeout_msecs")) {
rc = kstrtoint(buf, 0, &orangefs_dcache_timeout_msecs);
goto out;
......@@ -818,6 +836,9 @@ static struct orangefs_attribute op_timeout_secs_attribute =
static struct orangefs_attribute slot_timeout_secs_attribute =
__ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
static struct orangefs_attribute cache_timeout_msecs_attribute =
__ATTR(cache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
static struct orangefs_attribute dcache_timeout_msecs_attribute =
__ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
......@@ -861,6 +882,7 @@ static struct orangefs_attribute perf_time_interval_secs_attribute =
static struct attribute *orangefs_default_attrs[] = {
&op_timeout_secs_attribute.attr,
&slot_timeout_secs_attribute.attr,
&cache_timeout_msecs_attribute.attr,
&dcache_timeout_msecs_attribute.attr,
&getattr_timeout_msecs_attribute.attr,
&readahead_count_attribute.attr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment