From 44e24ae5d7dc41e54d23638d5f64ab2e81e43ad0 Mon Sep 17 00:00:00 2001 From: Cheyenne Wills Date: Thu, 9 Jun 2022 13:20:02 -0600 Subject: [PATCH] afs: introduce get_dcache_readahead Relocate the block of code that obtains the dcache for a readahead operation from the afs_linux_readpages function into its own static function. Change-Id: Iaaf9523532e292a1f2426d5ced65ddfbceb5d060 Reviewed-on: https://gerrit.openafs.org/14962 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- src/afs/LINUX/osi_vnodeops.c | 114 ++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index b4b1016787..6bf0019b9d 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -2734,6 +2734,81 @@ afs_linux_readpage(struct file *fp, struct page *pp) return code; } +/* + * Updates the adc and acacheFp parameters + * Returns: + * 0 - success + * -1 - problem getting inode or no mapping function + */ +static int +get_dcache_readahead(struct dcache **adc, struct file **acacheFp, + struct vcache *avc, loff_t offset) +{ + struct dcache *tdc = *adc; + struct file *cacheFp = *acacheFp; + int code; + + if (tdc != NULL && tdc->f.chunk != AFS_CHUNK(offset)) { + AFS_GLOCK(); + ReleaseReadLock(&tdc->lock); + afs_PutDCache(tdc); + AFS_GUNLOCK(); + tdc = NULL; + if (cacheFp != NULL) { + filp_close(cacheFp, NULL); + cacheFp = NULL; + } + } + + if (tdc == NULL) { + AFS_GLOCK(); + tdc = afs_FindDCache(avc, offset); + if (tdc != NULL) { + ObtainReadLock(&tdc->lock); + if (!afs_IsDCacheFresh(tdc, avc) || + (tdc->dflags & DFFetching) != 0) { + ReleaseReadLock(&tdc->lock); + afs_PutDCache(tdc); + tdc = NULL; + } + } + AFS_GUNLOCK(); + if (tdc != NULL) { + cacheFp = afs_linux_raw_open(&tdc->f.inode); + if (cacheFp == NULL) { + /* Problem getting the inode */ + code = -1; + goto out; + } + if (cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage == NULL) { + cachefs_noreadpage = 1; + /* No mapping function */ + code = -1; + goto out; + } + } + } + code = 0; + + out: + if (code != 0) { + if (cacheFp != NULL) { + filp_close(cacheFp, NULL); + cacheFp = NULL; + } + if (tdc != NULL) { + AFS_GLOCK(); + ReleaseReadLock(&tdc->lock); + afs_PutDCache(tdc); + AFS_GUNLOCK(); + tdc = NULL; + } + } + *adc = tdc; + *acacheFp = cacheFp; + return code; +} + /* Readpages reads a number of pages for a particular file. We use * this to optimise the reading, by limiting the number of times upon which * we have to lookup, lock and open vcaches and dcaches @@ -2783,42 +2858,9 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, list_del(&page->lru); offset = page_offset(page); - if (tdc && tdc->f.chunk != AFS_CHUNK(offset)) { - AFS_GLOCK(); - ReleaseReadLock(&tdc->lock); - afs_PutDCache(tdc); - AFS_GUNLOCK(); - tdc = NULL; - if (cacheFp) { - filp_close(cacheFp, NULL); - cacheFp = NULL; - } - } - - if (!tdc) { - AFS_GLOCK(); - if ((tdc = afs_FindDCache(avc, offset))) { - ObtainReadLock(&tdc->lock); - if (!afs_IsDCacheFresh(tdc, avc) || - (tdc->dflags & DFFetching)) { - ReleaseReadLock(&tdc->lock); - afs_PutDCache(tdc); - tdc = NULL; - } - } - AFS_GUNLOCK(); - if (tdc) { - cacheFp = afs_linux_raw_open(&tdc->f.inode); - if (cacheFp == NULL) { - /* Problem getting the inode */ - goto out; - } - if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) { - cachefs_noreadpage = 1; - goto out; - } - } - } + code = get_dcache_readahead(&tdc, &cacheFp, avc, offset); + if (code != 0) + goto out; if (tdc && !add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {