From: Cheyenne Wills Date: Wed, 29 Apr 2020 22:26:02 +0000 (-0600) Subject: libafs: Abstract the Linux lru cache interface X-Git-Tag: openafs-devel-1_9_0~83 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=dca95bcb7efdff38564dcff3e8f4189735f13b3a;hp=44b7b93b593371bfdddd0be0ae603f4f8720f78b libafs: Abstract the Linux lru cache interface Define static functions afs_lru_cache_init, afs_lru_cache_add and afs_lru_cache_finalize to handle interfacing with Linux's lru facilities. This change's primary purpose is to isolate the preprocessor conditionals associated with the details of the system lru interfaces to just these functions and to simplify the areas that utilize lru caching by removing the preprocessor conditionals. As Linux's lru facilities change, additional conditional code will be needed. Change-Id: I74c94bb712359975e3fd1df85f1b338b215f61b0 Reviewed-on: https://gerrit.openafs.org/14167 Reviewed-by: Andrew Deason Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 4617a34..df50a90 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -39,10 +39,6 @@ #include "osi_compat.h" #include "osi_pagecopy.h" -#ifndef HAVE_LINUX_PAGEVEC_LRU_ADD_FILE -#define __pagevec_lru_add_file __pagevec_lru_add -#endif - #ifndef MAX_ERRNO #define MAX_ERRNO 1000L #endif @@ -69,6 +65,41 @@ extern struct backing_dev_info *afs_backing_dev_info; extern struct vcache *afs_globalVp; +/* Handle interfacing with Linux's pagevec/lru facilities */ + +struct afs_lru_pages { + struct pagevec lrupv; +}; + +static inline void +afs_lru_cache_init(struct afs_lru_pages *alrupages) +{ +#if defined(PAGEVEC_INIT_COLD_ARG) + pagevec_init(&alrupages->lrupv, 0); +#else + pagevec_init(&alrupages->lrupv); +#endif +} + +#ifndef HAVE_LINUX_PAGEVEC_LRU_ADD_FILE +# define __pagevec_lru_add_file __pagevec_lru_add +#endif + +static inline void +afs_lru_cache_add(struct afs_lru_pages *alrupages, struct page *page) +{ + get_page(page); + if (!pagevec_add(&alrupages->lrupv, page)) + __pagevec_lru_add_file(&alrupages->lrupv); +} + +static inline void +afs_lru_cache_finalize(struct afs_lru_pages *alrupages) +{ + if (pagevec_count(&alrupages->lrupv)) + __pagevec_lru_add_file(&alrupages->lrupv); +} + /* This function converts a positive error code from AFS into a negative * code suitable for passing into the Linux VFS layer. It checks that the * error code is within the permissable bounds for the ERR_PTR mechanism. @@ -2079,7 +2110,7 @@ afs_linux_put_link(struct dentry *dentry, struct nameidata *nd) */ static int afs_linux_read_cache(struct file *cachefp, struct page *page, - int chunk, struct pagevec *lrupv, + int chunk, struct afs_lru_pages *alrupages, struct afs_pagecopy_task *task) { loff_t offset = page_offset(page); struct inode *cacheinode = cachefp->f_dentry->d_inode; @@ -2121,11 +2152,7 @@ afs_linux_read_cache(struct file *cachefp, struct page *page, if (code == 0) { cachepage = newpage; newpage = NULL; - - get_page(cachepage); - if (!pagevec_add(lrupv, cachepage)) - __pagevec_lru_add_file(lrupv); - + afs_lru_cache_add(alrupages, cachepage); } else { put_page(newpage); newpage = NULL; @@ -2185,7 +2212,7 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep) struct file *cacheFp = NULL; int code; int dcLocked = 0; - struct pagevec lrupv; + struct afs_lru_pages lrupages; /* Not a UFS cache, don't do anything */ if (cacheDiskType != AFS_FCACHE_TYPE_UFS) @@ -2271,16 +2298,12 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep) AFS_GLOCK(); goto out; } -#if defined(PAGEVEC_INIT_COLD_ARG) - pagevec_init(&lrupv, 0); -#else - pagevec_init(&lrupv); -#endif - code = afs_linux_read_cache(cacheFp, pp, tdc->f.chunk, &lrupv, NULL); + afs_lru_cache_init(&lrupages); - if (pagevec_count(&lrupv)) - __pagevec_lru_add_file(&lrupv); + code = afs_linux_read_cache(cacheFp, pp, tdc->f.chunk, &lrupages, NULL); + + afs_lru_cache_finalize(&lrupages); filp_close(cacheFp, NULL); AFS_GLOCK(); @@ -2410,7 +2433,7 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, struct iovec* iovecp; struct nocache_read_request *ancr; struct page *pp; - struct pagevec lrupv; + struct afs_lru_pages lrupages; afs_int32 code = 0; cred_t *credp; @@ -2435,11 +2458,7 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, ancr->offset = auio->uio_offset; ancr->length = auio->uio_resid; -#if defined(PAGEVEC_INIT_COLD_ARG) - pagevec_init(&lrupv, 0); -#else - pagevec_init(&lrupv); -#endif + afs_lru_cache_init(&lrupages); for(page_ix = 0; page_ix < num_pages; ++page_ix) { @@ -2485,27 +2504,18 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, lock_page(pp); } - /* increment page refcount--our original design assumed - * that locking it would effectively pin it; protect - * ourselves from the possiblity that this assumption is - * is faulty, at low cost (provided we do not fail to - * do the corresponding decref on the other side) */ - get_page(pp); - /* save the page for background map */ iovecp[page_ix].iov_base = (void*) pp; /* and put it on the LRU cache */ - if (!pagevec_add(&lrupv, pp)) - __pagevec_lru_add_file(&lrupv); + afs_lru_cache_add(&lrupages, pp); } } /* If there were useful pages in the page list, make sure all pages * are in the LRU cache, then schedule the read */ if(page_count) { - if (pagevec_count(&lrupv)) - __pagevec_lru_add_file(&lrupv); + afs_lru_cache_finalize(&lrupages); credp = crref(); code = afs_ReadNoCache(avc, ancr, credp); crfree(credp); @@ -2636,7 +2646,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, int code; unsigned int page_idx; loff_t offset; - struct pagevec lrupv; + struct afs_lru_pages lrupages; struct afs_pagecopy_task *task; if (afs_linux_bypass_check(inode)) @@ -2661,11 +2671,9 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, task = afs_pagecopy_init_task(); tdc = NULL; -#if defined(PAGEVEC_INIT_COLD_ARG) - pagevec_init(&lrupv, 0); -#else - pagevec_init(&lrupv); -#endif + + afs_lru_cache_init(&lrupages); + for (page_idx = 0; page_idx < num_pages; page_idx++) { struct page *page = list_entry(page_list->prev, struct page, lru); list_del(&page->lru); @@ -2705,18 +2713,15 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, if (tdc && !add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { - get_page(page); - if (!pagevec_add(&lrupv, page)) - __pagevec_lru_add_file(&lrupv); + afs_lru_cache_add(&lrupages, page); /* Note that add_to_page_cache() locked 'page'. * afs_linux_read_cache() is guaranteed to handle unlocking it. */ - afs_linux_read_cache(cacheFp, page, tdc->f.chunk, &lrupv, task); + afs_linux_read_cache(cacheFp, page, tdc->f.chunk, &lrupages, task); } put_page(page); } - if (pagevec_count(&lrupv)) - __pagevec_lru_add_file(&lrupv); + afs_lru_cache_finalize(&lrupages); out: if (tdc)