From 80fe111f0044aa7a67215ad92210dc72cb7eb2c0 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Tue, 10 May 2011 14:16:06 -0500 Subject: [PATCH] libafs: Flush vcaches in afs_shutdown Currently, a few platforms (linux, linux24, solaris, irix) flush all vcaches during shutdown. However, they do this before calling afs_shutdown(), resulting in afs_FlushVCache queueing VCBs and possibly trying to give the callbacks back to the server. Instead of this, perform the flushes in afs_shutdown itself, so we do this after we try to give up all callbacks to all servers, and we do this while afs_shuttingdown is set, so we don't try to queue VCBs. This also consolidates some of the duplicated code to flush all vcaches, and now does this for all platforms. Change-Id: I69c9e0862972f18ecc29ff709943d9a77f2db0a9 Reviewed-on: http://gerrit.openafs.org/4641 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/afs/LINUX/osi_prototypes.h | 1 - src/afs/LINUX/osi_vfsops.c | 31 +------------------------------ src/afs/LINUX24/osi_prototypes.h | 1 - src/afs/LINUX24/osi_vfsops.c | 29 ----------------------------- src/afs/SOLARIS/osi_vfsops.c | 12 ------------ src/afs/afs_call.c | 6 +++++- src/afs/afs_prototypes.h | 1 + src/afs/afs_vcache.c | 27 +++++++++++++++++++++++++++ 8 files changed, 34 insertions(+), 74 deletions(-) diff --git a/src/afs/LINUX/osi_prototypes.h b/src/afs/LINUX/osi_prototypes.h index 33c7cd134..c91500c1d 100644 --- a/src/afs/LINUX/osi_prototypes.h +++ b/src/afs/LINUX/osi_prototypes.h @@ -83,7 +83,6 @@ extern void osi_VM_Truncate(struct vcache *avc, int alen, extern void vattr2inode(struct inode *ip, struct vattr *vp); extern int afs_init_inodecache(void); extern void afs_destroy_inodecache(void); -extern void osi_linux_free_inode_pages(void); /* osi_vnodeops.c */ extern void afs_fill_inode(struct inode *ip, struct vattr *vattr); diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index 04ddafc9f..596d0644f 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -146,7 +146,7 @@ afs_fill_super(struct super_block *sb, void *data, int silent) code = afs_root(sb); if (code) { afs_globalVFS = NULL; - osi_linux_free_inode_pages(); + afs_FlushAllVCaches(); module_put(THIS_MODULE); } @@ -341,7 +341,6 @@ afs_put_super(struct super_block *sbp) afs_globalVFS = 0; afs_globalVp = 0; - osi_linux_free_inode_pages(); /* invalidate and release remaining AFS inodes. */ afs_shutdown(); mntput(afs_cacheMnt); @@ -464,31 +463,3 @@ vattr2inode(struct inode *ip, struct vattr *vp) ip->i_ctime.tv_sec = vp->va_ctime.tv_sec; ip->i_ctime.tv_nsec = 0; } - -/* osi_linux_free_inode_pages - * - * Free all vnodes remaining in the afs hash. Must be done before - * shutting down afs and freeing all memory. - */ -void -osi_linux_free_inode_pages(void) -{ - int i; - struct vcache *tvc, *nvc; - extern struct vcache *afs_vhashT[VCSIZE]; - - retry: - for (i = 0; i < VCSIZE; i++) { - for (tvc = afs_vhashT[i]; tvc; ) { - int slept; - - nvc = tvc->hnext; - if (afs_FlushVCache(tvc, &slept)) - printf("Failed to invalidate all pages on inode 0x%p\n", tvc); - if (slept) { - goto retry; - } - tvc = nvc; - } - } -} diff --git a/src/afs/LINUX24/osi_prototypes.h b/src/afs/LINUX24/osi_prototypes.h index c32830581..5a1e59e92 100644 --- a/src/afs/LINUX24/osi_prototypes.h +++ b/src/afs/LINUX24/osi_prototypes.h @@ -83,7 +83,6 @@ extern void osi_VM_Truncate(struct vcache *avc, int alen, extern void vattr2inode(struct inode *ip, struct vattr *vp); extern int afs_init_inodecache(void); extern void afs_destroy_inodecache(void); -extern void osi_linux_free_inode_pages(void); /* osi_vnodeops.c */ extern void afs_fill_inode(struct inode *ip, struct vattr *vattr); diff --git a/src/afs/LINUX24/osi_vfsops.c b/src/afs/LINUX24/osi_vfsops.c index 702177c0a..8b9cdea3d 100644 --- a/src/afs/LINUX24/osi_vfsops.c +++ b/src/afs/LINUX24/osi_vfsops.c @@ -325,7 +325,6 @@ afs_put_super(struct super_block *sbp) afs_globalVFS = 0; afs_globalVp = 0; - osi_linux_free_inode_pages(); /* invalidate and release remaining AFS inodes. */ afs_shutdown(); #if defined(AFS_LINUX24_ENV) mntput(afs_cacheMnt); @@ -452,31 +451,3 @@ vattr2inode(struct inode *ip, struct vattr *vp) ip->i_mtime = vp->va_mtime.tv_sec; ip->i_ctime = vp->va_ctime.tv_sec; } - -/* osi_linux_free_inode_pages - * - * Free all vnodes remaining in the afs hash. Must be done before - * shutting down afs and freeing all memory. - */ -void -osi_linux_free_inode_pages(void) -{ - int i; - struct vcache *tvc, *nvc; - extern struct vcache *afs_vhashT[VCSIZE]; - - retry: - for (i = 0; i < VCSIZE; i++) { - for (tvc = afs_vhashT[i]; tvc; ) { - int slept; - - nvc = tvc->hnext; - if (afs_FlushVCache(tvc, &slept)) - printf("Failed to invalidate all pages on inode 0x%p\n", tvc); - if (slept) { - goto retry; - } - tvc = nvc; - } - } -} diff --git a/src/afs/SOLARIS/osi_vfsops.c b/src/afs/SOLARIS/osi_vfsops.c index f923e4ef9..dbc76ab78 100644 --- a/src/afs/SOLARIS/osi_vfsops.c +++ b/src/afs/SOLARIS/osi_vfsops.c @@ -80,18 +80,6 @@ afs_freevfs(void) afs_globalVFS = 0; - /* free mappings for all vcaches */ - for (i = 0; i < VCSIZE; i++) { - for (vc = afs_vhashT[i]; vc; vc = nvc) { - int fv_slept; - nvc = vc->hnext; - if (afs_FlushVCache(vc, &fv_slept)) { - afs_warn("afs_FlushVCache failed on 0x%llx\n", - (unsigned long long)vc); - } - } - } - afs_shutdown(); } diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 74002368f..8d972dd86 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -1378,7 +1378,11 @@ afs_shutdown(void) afs_warn("afs: COLD "); else afs_warn("afs: WARM "); - afs_warn("shutting down of: CB... "); + afs_warn("shutting down of: vcaches... "); + + afs_FlushAllVCaches(); + + afs_warn("CB... "); afs_termState = AFSOP_STOP_RXCALLBACK; rx_WakeupServerProcs(); diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 95f8ba0b8..efcf6226c 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -1067,6 +1067,7 @@ extern struct vcache *afs_LookupVCache(struct VenusFid *afid, struct vrequest *areq, afs_int32 * cached, struct vcache *adp, char *aname); +extern void afs_FlushAllVCaches(void); extern int afs_FlushVCache(struct vcache *avc, int *slept); extern struct vcache *afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 68704635a..e577230c1 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -831,6 +831,33 @@ afs_PrePopulateVCache(struct vcache *avc, struct VenusFid *afid, #endif } +void +afs_FlushAllVCaches(void) +{ + int i; + struct vcache *tvc, *nvc; + + ObtainWriteLock(&afs_xvcache, 867); + + retry: + for (i = 0; i < VCSIZE; i++) { + for (tvc = afs_vhashT[i]; tvc; tvc = nvc) { + int slept; + + nvc = tvc->hnext; + if (afs_FlushVCache(tvc, &slept)) { + afs_warn("Failed to flush vcache 0x%lx\n", (unsigned long)(uintptr_t)tvc); + } + if (slept) { + goto retry; + } + tvc = nvc; + } + } + + ReleaseWriteLock(&afs_xvcache); +} + /*! * This routine is responsible for allocating a new cache entry * from the free list. It formats the cache entry and inserts it -- 2.39.5