]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
libafs: Abstract the Linux lru cache interface
authorCheyenne Wills <cwills@sinenomine.net>
Fri, 15 May 2020 16:39:53 +0000 (10:39 -0600)
committerStephan Wiesand <stephan.wiesand@desy.de>
Fri, 12 Jun 2020 15:39:15 +0000 (11:39 -0400)
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.

Reviewed-on: https://gerrit.openafs.org/14167
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit dca95bcb7efdff38564dcff3e8f4189735f13b3a)

Change-Id: I863bbc9bb578716c42fdf34672ec8ad85f05ea31
Reviewed-on: https://gerrit.openafs.org/14209
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
src/afs/LINUX/osi_vnodeops.c

index 03635212cdd791be345cff9080e8f651a3e67e5d..96d7a2e33b86be1c0fd191b777f99089a0b62a2a 100644 (file)
 #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.
@@ -2093,7 +2124,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;
@@ -2135,11 +2166,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;
@@ -2199,7 +2226,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)
@@ -2285,16 +2312,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();
@@ -2424,7 +2447,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;
@@ -2449,11 +2472,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) {
 
@@ -2499,27 +2518,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);
@@ -2650,7 +2660,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))
@@ -2675,11 +2685,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);
@@ -2719,18 +2727,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)