diff options
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.patch | 255 |
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 + |