orangefs: remember count when reading.
Orangefs wins when it can do IO on large (up to four meg) blocks at a time, and looses when it has to do tiny "small io" reads and writes. Accessing Orangefs through the pagecache with the kernel module helps with small io, both reading and writing, a great deal. Readpage generally tries to fetch a page (four k) at a time. We'll let users use "count" (as in read(2) or pread(2) for example) as a knob to control how much data they get from Orangefs at a time and we'll try to use the data to fill extra pagecache pages when we get to ->readpage, hopefully resulting in fewer calls to readpage and Orangefs userspace. We need a way to remember how they set count so that we can still have it available when we get to ->readpage. - We'll use file->private_data to keep track of "count". We'll wrap generic_file_open with orangefs_file_open and initialize private_data to NULL there. - In ->read_iter we have access to both "count" and file, so we'll kmalloc some space onto file->private_data and store "count" there. - We'll kfree file->private_data each time we visit ->flush and reinitialize it to NULL. Signed-off-by: Mike Marshall <hubcap@omnibond.com> Signed-off-by: Martin Brandenburg <martin@omnibond.com>
This commit is contained in:
parent
8f04e1be78
commit
c2549f8c7a
|
@ -286,8 +286,23 @@ static ssize_t orangefs_file_read_iter(struct kiocb *iocb,
|
|||
struct iov_iter *iter)
|
||||
{
|
||||
int ret;
|
||||
struct orangefs_read_options *ro;
|
||||
|
||||
orangefs_stats.reads++;
|
||||
|
||||
/*
|
||||
* Remember how they set "count" in read(2) or pread(2) or whatever -
|
||||
* users can use count as a knob to control orangefs io size and later
|
||||
* we can try to help them fill as many pages as possible in readpage.
|
||||
*/
|
||||
if (!iocb->ki_filp->private_data) {
|
||||
iocb->ki_filp->private_data = kmalloc(sizeof *ro, GFP_KERNEL);
|
||||
if (!iocb->ki_filp->private_data)
|
||||
return(ENOMEM);
|
||||
ro = iocb->ki_filp->private_data;
|
||||
ro->blksiz = iter->count;
|
||||
}
|
||||
|
||||
down_read(&file_inode(iocb->ki_filp)->i_rwsem);
|
||||
ret = orangefs_revalidate_mapping(file_inode(iocb->ki_filp));
|
||||
if (ret)
|
||||
|
@ -556,6 +571,12 @@ static int orangefs_lock(struct file *filp, int cmd, struct file_lock *fl)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int orangefs_file_open(struct inode * inode, struct file *file)
|
||||
{
|
||||
file->private_data = NULL;
|
||||
return generic_file_open(inode, file);
|
||||
}
|
||||
|
||||
static int orangefs_flush(struct file *file, fl_owner_t id)
|
||||
{
|
||||
/*
|
||||
|
@ -569,6 +590,9 @@ static int orangefs_flush(struct file *file, fl_owner_t id)
|
|||
struct inode *inode = file->f_mapping->host;
|
||||
int r;
|
||||
|
||||
kfree(file->private_data);
|
||||
file->private_data = NULL;
|
||||
|
||||
if (inode->i_state & I_DIRTY_TIME) {
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_state &= ~I_DIRTY_TIME;
|
||||
|
@ -591,7 +615,7 @@ const struct file_operations orangefs_file_operations = {
|
|||
.lock = orangefs_lock,
|
||||
.unlocked_ioctl = orangefs_ioctl,
|
||||
.mmap = orangefs_file_mmap,
|
||||
.open = generic_file_open,
|
||||
.open = orangefs_file_open,
|
||||
.flush = orangefs_flush,
|
||||
.release = orangefs_file_release,
|
||||
.fsync = orangefs_fsync,
|
||||
|
|
|
@ -239,6 +239,10 @@ struct orangefs_write_range {
|
|||
kgid_t gid;
|
||||
};
|
||||
|
||||
struct orangefs_read_options {
|
||||
ssize_t blksiz;
|
||||
};
|
||||
|
||||
extern struct orangefs_stats orangefs_stats;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue