mirror of
https://git.openafs.org/openafs.git
synced 2025-01-19 15:30:14 +00:00
Use readpage, not read for fastpath access
Modify the fast path case so that it uses readpage(), rather than read() to access data in the cache. This removes a lot of the hidden, uncessary work that the kernel was doing behind the scenes, and takes advantage of the fact that we know a page read will always result in a page read against the backing cache. Reviewed-on: http://gerrit.openafs.org/535 Tested-by: Derrick Brashear <shadow@dementia.org> Reviewed-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
parent
c4bffd7efb
commit
88a037585d
@ -1773,15 +1773,16 @@ out:
|
||||
static int inline
|
||||
afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep)
|
||||
{
|
||||
afs_offs_t offset = ((loff_t) pp->index) << PAGE_CACHE_SHIFT;
|
||||
loff_t offset = page_offset(pp);
|
||||
struct inode *ip = FILE_INODE(fp);
|
||||
struct vcache *avc = VTOAFS(ip);
|
||||
struct dcache *tdc;
|
||||
struct file *cacheFp;
|
||||
char *address;
|
||||
int dcLocked;
|
||||
ssize_t size;
|
||||
mm_segment_t old_fs;
|
||||
struct page *newpage, *backpage;
|
||||
struct address_space *bmapping;
|
||||
int pageindex;
|
||||
int code;
|
||||
int dcLocked = 0;
|
||||
|
||||
/* Not a UFS cache, don't do anything */
|
||||
if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
|
||||
@ -1858,34 +1859,66 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep)
|
||||
|
||||
/* Okay, so we've now got a cache file that is up to date */
|
||||
|
||||
offset -= AFS_CHUNKTOBASE(tdc->f.chunk);
|
||||
|
||||
/* XXX - I suspect we should be locking the inodes before we use them! */
|
||||
AFS_GUNLOCK();
|
||||
cacheFp = afs_linux_raw_open(&tdc->f.inode, NULL);
|
||||
if (cacheFp->f_op->llseek)
|
||||
cacheFp->f_op->llseek(cacheFp, offset, 0);
|
||||
else
|
||||
cacheFp->f_pos = offset;
|
||||
|
||||
address = kmap(pp);
|
||||
ClearPageError(pp);
|
||||
old_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
size = cacheFp->f_op->read(cacheFp, address, PAGE_SIZE, &cacheFp->f_pos);
|
||||
set_fs(old_fs);
|
||||
bmapping = cacheFp->f_dentry->d_inode->i_mapping;
|
||||
newpage = NULL;
|
||||
backpage = NULL;
|
||||
|
||||
if (size >= 0) {
|
||||
if (size != PAGE_SIZE)
|
||||
memset((void *)(address + size), 0, PAGE_SIZE - size);
|
||||
size = 0;
|
||||
flush_dcache_page(pp);
|
||||
SetPageUptodate(pp);
|
||||
/* From our offset, we now need to work out which page in the disk
|
||||
* file it corresponds to. This will be fun ... */
|
||||
pageindex = (offset - AFS_CHUNKTOBASE(tdc->f.chunk)) >> PAGE_CACHE_SHIFT;
|
||||
|
||||
while (backpage == NULL) {
|
||||
backpage = find_get_page(bmapping, pageindex);
|
||||
if (!backpage) {
|
||||
if (!newpage)
|
||||
newpage = page_cache_alloc_cold(bmapping);
|
||||
if (!newpage)
|
||||
goto out;
|
||||
|
||||
code = add_to_page_cache(newpage, bmapping, pageindex, GFP_KERNEL);
|
||||
if (code == 0) {
|
||||
backpage = newpage;
|
||||
newpage = NULL;
|
||||
|
||||
page_cache_get(backpage);
|
||||
} else {
|
||||
page_cache_release(newpage);
|
||||
newpage = NULL;
|
||||
if (code != -EEXIST)
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
lock_page(backpage);
|
||||
}
|
||||
}
|
||||
|
||||
kunmap(pp);
|
||||
if (!PageUptodate(backpage)) {
|
||||
ClearPageError(backpage);
|
||||
code = bmapping->a_ops->readpage(NULL, backpage);
|
||||
if (!code) {
|
||||
wait_on_page_locked(backpage);
|
||||
if (!PageUptodate(backpage))
|
||||
code = -EIO;
|
||||
}
|
||||
} else {
|
||||
unlock_page(backpage);
|
||||
}
|
||||
|
||||
if (!code) {
|
||||
copy_highpage(pp, backpage);
|
||||
flush_dcache_page(pp);
|
||||
SetPageUptodate(pp);
|
||||
}
|
||||
UnlockPage(pp);
|
||||
|
||||
out:
|
||||
if (backpage)
|
||||
page_cache_release(backpage);
|
||||
|
||||
filp_close(cacheFp, NULL);
|
||||
AFS_GLOCK();
|
||||
|
||||
@ -1893,7 +1926,7 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep)
|
||||
ReleaseWriteLock(&avc->lock);
|
||||
afs_PutDCache(tdc);
|
||||
|
||||
*codep = size;
|
||||
*codep = code;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user