From 38207faabe6641e97d177160f45ccdaef8cef8ab Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Thu, 26 Apr 2018 12:02:18 -0500 Subject: [PATCH] afs: Avoid GetDCache panic on AllocDCache failure Currently, in afs_GetDCache, if afs_AllocDCache fails, we retry for 5 minutes and then panic. Panicing in this situation is completely unnecessary; afs_GetDCache can fail for a variety of other mundane reasons (such as, if we can't fetch the requested data from the relevant fileserver). It may seem unusual for afs_AllocDCache to fail for over 5 minutes (this is supposed to mean that we're out of dslots, and our attempts to free up dslots have failed). However, afs_AllocDCache can also fail if we are having issues in accessing the disk cache, and so we may not be out of cache space or dslots at all; we just can't access the cache. In this case, afs_AllocDCache can easily fail forever; waiting longer or trying to free up cache space isn't going to help. So, to avoid panicing in such situations, just make afs_GetDCache return an error. We just need to make sure afs_xdcache is unlocked, and then we can just jump to 'done', like plenty of other codepaths do; no extra cleanup is required. Also since we are removing a panic, add a log message when this situation happens, so EIO errors don't suddenly pop up silently. Reviewed-on: https://gerrit.openafs.org/13032 Reviewed-by: Mark Vitale Reviewed-by: Benjamin Kaduk Reviewed-by: Michael Meffie Reviewed-by: Marcio Brito Barbosa Tested-by: BuildBot (cherry picked from commit 0ff2364bd5e68c0a7587f8fbc552bf20b99d7039) Change-Id: Ie29eed271b490edc943929710a87550e2d67b735 Reviewed-on: https://gerrit.openafs.org/13189 Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Michael Meffie Reviewed-by: Joe Gorse Reviewed-by: Marcio Brito Barbosa Reviewed-by: Benjamin Kaduk --- src/afs/afs_dcache.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index f71f459c4..659e5ef31 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -1971,10 +1971,19 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, } tdc = afs_AllocDCache(avc, chunk, aflags, NULL); if (!tdc) { - /* If we can't get space for 5 mins we give up and panic */ - if (++downDCount > 300) - osi_Panic("getdcache"); ReleaseWriteLock(&afs_xdcache); + + /* If we can't get space for 5 mins we give up and bail out */ + if (++downDCount > 300) { + afs_warn("afs: Unable to get free cache space for file " + "%u:%u.%u.%u for 5 minutes; failing with an i/o error\n", + avc->f.fid.Cell, + avc->f.fid.Fid.Volume, + avc->f.fid.Fid.Vnode, + avc->f.fid.Fid.Unique); + goto done; + } + /* * Locks held: * avc->lock(R) if setLocks -- 2.39.5