summarylogtreecommitdiffstats
path: root/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch
diff options
context:
space:
mode:
Diffstat (limited to '0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch')
-rw-r--r--0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch255
1 files changed, 255 insertions, 0 deletions
diff --git a/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch b/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch
new file mode 100644
index 000000000000..c6289b54415f
--- /dev/null
+++ b/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch
@@ -0,0 +1,255 @@
+From 3a0dbbb40e89ae0f0ec901c5fa831a2c1a5ca9a3 Mon Sep 17 00:00:00 2001
+From: Cheyenne Wills <cwills@sinenomine.net>
+Date: Wed, 1 Jun 2022 09:10:12 -0600
+Subject: [PATCH 08/12] afs: introduce afs_alloc_ncr/afs_free_ncr
+
+There is duplicated code for initializing a nocache_read_request
+and also freeing the associated storage in certain cases. Create a set
+of helper functions that allocates and frees a nocache_read_request and
+its associated structures.
+
+afs_alloc_ncr allocates a nocache_read_request structure and if not
+UKERNEL, will allocate and initialize the associated uio and iovec
+structures.
+
+afs_free_ncr releases a noncache_read_request structure and the
+associated uio and iovec structures if not UKERNEL.
+
+Update locations that allocate/free nocache_read_request structures to
+use the new functions.
+
+Change-Id: I80c0b4eb036bcb1223b73f4c1de2c12be362de42
+---
+ src/afs/LINUX/osi_vnodeops.c | 37 +++++++-----------
+ src/afs/UKERNEL/afs_usrops.c | 8 +++-
+ src/afs/afs_bypasscache.c | 73 +++++++++++++++++++++++++++++++-----
+ src/afs/afs_bypasscache.h | 3 +-
+ 4 files changed, 85 insertions(+), 36 deletions(-)
+
+diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
+index a0c78c04d..9b5d05471 100644
+--- a/src/afs/LINUX/osi_vnodeops.c
++++ b/src/afs/LINUX/osi_vnodeops.c
+@@ -2537,7 +2537,6 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping,
+ struct list_head *page_list, unsigned num_pages)
+ {
+ afs_int32 page_ix;
+- struct uio *auio;
+ afs_offs_t offset;
+ struct iovec* iovecp;
+ struct nocache_read_request *ancr;
+@@ -2552,20 +2551,10 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping,
+ afs_int32 page_count = 0;
+ afs_int32 isize;
+
+- /* background thread must free: iovecp, auio, ancr */
+- iovecp = osi_Alloc(num_pages * sizeof(struct iovec));
+-
+- auio = osi_Alloc(sizeof(struct uio));
+- auio->uio_iov = iovecp;
+- auio->uio_iovcnt = num_pages;
+- auio->uio_flag = UIO_READ;
+- auio->uio_seg = AFS_UIOSYS;
+- auio->uio_resid = num_pages * PAGE_SIZE;
+-
+- ancr = osi_Alloc(sizeof(struct nocache_read_request));
+- ancr->auio = auio;
+- ancr->offset = auio->uio_offset;
+- ancr->length = auio->uio_resid;
++ ancr = afs_alloc_ncr(num_pages);
++ if (ancr == NULL)
++ return afs_convert_code(ENOMEM);
++ iovecp = ancr->auio->uio_iov;
+
+ afs_lru_cache_init(&lrupages);
+
+@@ -2587,7 +2576,7 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping,
+
+ if(page_ix == 0) {
+ offset = page_offset(pp);
+- ancr->offset = auio->uio_offset = offset;
++ ancr->offset = ancr->auio->uio_offset = offset;
+ base_index = pp->index;
+ }
+ iovecp[page_ix].iov_len = PAGE_SIZE;
+@@ -2626,14 +2615,13 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping,
+ if(page_count) {
+ afs_lru_cache_finalize(&lrupages);
+ credp = crref();
++ /* background thread frees the ancr */
+ code = afs_ReadNoCache(avc, ancr, credp);
+ crfree(credp);
+ } else {
+ /* If there is nothing for the background thread to handle,
+ * it won't be freeing the things that we never gave it */
+- osi_Free(iovecp, num_pages * sizeof(struct iovec));
+- osi_Free(auio, sizeof(struct uio));
+- osi_Free(ancr, sizeof(struct nocache_read_request));
++ afs_free_ncr(&ancr);
+ }
+ /* we do not flush, release, or unmap pages--that will be
+ * done for us by the background thread as each page comes in
+@@ -2665,8 +2653,13 @@ afs_linux_bypass_readpage(struct file *fp, struct page *pp)
+ ClearPageError(pp);
+
+ /* receiver frees */
+- auio = osi_Alloc(sizeof(struct uio));
+- iovecp = osi_Alloc(sizeof(struct iovec));
++ ancr = afs_alloc_ncr(1);
++ if (ancr == NULL) {
++ SetPageError(pp);
++ return afs_convert_code(ENOMEM);
++ }
++ auio = ancr->auio;
++ iovecp = auio->uio_iov;
+
+ /* address can be NULL, because we overwrite it with 'pp', below */
+ setup_uio(auio, iovecp, NULL, page_offset(pp),
+@@ -2676,8 +2669,6 @@ afs_linux_bypass_readpage(struct file *fp, struct page *pp)
+ get_page(pp); /* see above */
+ auio->uio_iov->iov_base = (void*) pp;
+ /* the background thread will free this */
+- ancr = osi_Alloc(sizeof(struct nocache_read_request));
+- ancr->auio = auio;
+ ancr->offset = page_offset(pp);
+ ancr->length = PAGE_SIZE;
+
+diff --git a/src/afs/UKERNEL/afs_usrops.c b/src/afs/UKERNEL/afs_usrops.c
+index 0e38fb84b..80403c5bd 100644
+--- a/src/afs/UKERNEL/afs_usrops.c
++++ b/src/afs/UKERNEL/afs_usrops.c
+@@ -2398,12 +2398,16 @@ uafs_pread_nocache_r(int fd, char *buf, int len, off_t offset)
+ }
+
+ /* these get freed in PrefetchNoCache, so... */
+- bparms = afs_osi_Alloc(sizeof(struct nocache_read_request));
++ bparms = afs_alloc_ncr(0);
++ if (bparms == NULL) {
++ errno = ENOMEM;
++ return -1;
++ }
+
+ code = afs_CreateReq(&bparms->areq, get_user_struct()->u_cred);
+ if (code) {
+ afs_DestroyReq(bparms->areq);
+- afs_osi_Free(bparms, sizeof(struct nocache_read_request));
++ afs_free_ncr(&bparms);
+ errno = code;
+ return -1;
+ }
+diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c
+index c51bd25c7..e13a32e9d 100644
+--- a/src/afs/afs_bypasscache.c
++++ b/src/afs/afs_bypasscache.c
+@@ -111,7 +111,68 @@
+ int cache_bypass_strategy = NEVER_BYPASS_CACHE;
+ afs_size_t cache_bypass_threshold = AFS_CACHE_BYPASS_DISABLED; /* file size > threshold triggers bypass */
+ int cache_bypass_prefetch = 1; /* Should we do prefetching ? */
++/*
++ * Allocate and initialize nocache_read_request/uid/iovec
++ * Returns NULL if memory allocation error.
++ */
++struct nocache_read_request *
++afs_alloc_ncr(unsigned num_pages)
++{
++ struct nocache_read_request *ancr = NULL;
++#if !defined(UKERNEL)
++ struct uio *auio = NULL;
++ struct iovec *iovecp = NULL;
++#endif
++
++ ancr = osi_Alloc(sizeof(*ancr));
++ if (ancr == NULL)
++ goto error;
+
++#if !defined(UKERNEL)
++ iovecp = osi_Alloc(num_pages * sizeof(*iovecp));
++ if (iovecp == NULL)
++ goto error;
++
++ auio = osi_Alloc(sizeof(*auio));
++ if (auio == NULL)
++ goto error;
++ auio->uio_iov = iovecp;
++ auio->uio_iovcnt = num_pages;
++ auio->uio_flag = UIO_READ;
++ auio->uio_seg = AFS_UIOSYS;
++ auio->uio_offset = 0;
++ auio->uio_resid = num_pages * PAGE_SIZE;
++
++ ancr->auio = auio;
++ ancr->offset = auio->uio_offset;
++ ancr->length = auio->uio_resid;
++#endif
++
++ return ancr;
++
++ error:
++#if !defined(UKERNEL)
++ osi_Free(iovecp, num_pages * sizeof(*iovecp));
++ osi_Free(auio, sizeof(*auio));
++#endif
++ osi_Free(ancr, sizeof(*ancr));
++ return NULL;
++}
++/*
++ * Free a nocache_read_request and associated structures
++ */
++void
++afs_free_ncr(struct nocache_read_request **ancr)
++{
++ if (*ancr == NULL)
++ return;
++#if !defined(UKERNEL)
++ osi_Free((*ancr)->auio->uio_iov, (*ancr)->auio->uio_iovcnt * sizeof(struct iovec));
++ osi_Free((*ancr)->auio, sizeof(struct uio));
++#endif
++ osi_Free(*ancr, sizeof(struct nocache_read_request));
++ *ancr = NULL;
++}
+ /*
+ * This is almost exactly like the PFlush() routine in afs_pioctl.c,
+ * but that routine is static. We are about to change a file from
+@@ -517,10 +578,7 @@ cleanup:
+ AFS_GLOCK();
+ afs_DestroyReq(areq);
+ AFS_GUNLOCK();
+- osi_Free(bparms->auio->uio_iov,
+- bparms->auio->uio_iovcnt * sizeof(struct iovec));
+- osi_Free(bparms->auio, sizeof(struct uio));
+- osi_Free(bparms, sizeof(struct nocache_read_request));
++ afs_free_ncr(&bparms);
+ return code;
+ }
+
+@@ -647,12 +705,7 @@ done:
+
+ afs_DestroyReq(areq);
+ osi_Free(tcallspec, sizeof(struct tlocal1));
+- osi_Free(bparms, sizeof(struct nocache_read_request));
+-#ifndef UKERNEL
+- /* in UKERNEL, the "pages" are passed in */
+- osi_Free(iovecp, auio->uio_iovcnt * sizeof(struct iovec));
+- osi_Free(auio, sizeof(struct uio));
+-#endif
++ afs_free_ncr(&bparms);
+ return code;
+ }
+ #endif
+diff --git a/src/afs/afs_bypasscache.h b/src/afs/afs_bypasscache.h
+index 37c5669b3..0c7542dd6 100644
+--- a/src/afs/afs_bypasscache.h
++++ b/src/afs/afs_bypasscache.h
+@@ -103,7 +103,8 @@ enum cache_bypass_strategies
+ extern int cache_bypass_prefetch;
+ extern int cache_bypass_strategy;
+ extern afs_size_t cache_bypass_threshold;
+-
++struct nocache_read_request *afs_alloc_ncr(unsigned num_pages);
++void afs_free_ncr(struct nocache_read_request **ancr);
+ void afs_TransitionToBypass(struct vcache *, afs_ucred_t *, int);
+ void afs_TransitionToCaching(struct vcache *, afs_ucred_t *, int);
+
+--
+2.36.1
+