From aed4a0c4b91c5ce185547e83bfff443f3d3831f9 Mon Sep 17 00:00:00 2001 From: Mark Vitale Date: Fri, 19 Jul 2019 14:41:55 -0400 Subject: [PATCH] afs: avoid panic in DNew when afs_WriteDCache fails afs_WriteDCache may fail for an IO error, or if interrupted (EINTR). Unfortunately, DNew will panic in this case, crashing the entire machine. In order to avoid an outage in this case, don't panic. Instead, reflect the error back to the caller of DNew. While here, add Doxygen comments to DNew. Change-Id: I27a8f89bab979c5691dded70e8b9eacbe8aff4fd Reviewed-on: https://gerrit.openafs.org/13804 Reviewed-by: Benjamin Kaduk Tested-by: BuildBot --- src/afs/afs_buffer.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/afs/afs_buffer.c b/src/afs/afs_buffer.c index 76c2b7c..ef0ee18 100644 --- a/src/afs/afs_buffer.c +++ b/src/afs/afs_buffer.c @@ -579,12 +579,24 @@ DFlush(void) return 0; } +/*! + * Prepare a new directory page buffer + * + * \param adc pointer to the directory object dcache + * \param nblobs page we want + * \param entry buffer to return requested page + * + * \retval 0 success; entry is updated + * \retval non-zero internal error or IO error writing to disk + */ int DNew(struct dcache *adc, int page, struct DirBuffer *entry) { /* Same as read, only do *not* even try to read the page, since it * probably doesn't exist. */ struct buffer *tb; + int code; + AFS_STATCNT(DNew); ObtainWriteLock(&afs_bufferLock, 264); @@ -599,7 +611,11 @@ DNew(struct dcache *adc, int page, struct DirBuffer *entry) * DFlush due to lock hierarchy issues */ if ((page + 1) * AFS_BUFFER_PAGESIZE > adc->f.chunkBytes) { afs_AdjustSize(adc, (page + 1) * AFS_BUFFER_PAGESIZE); - osi_Assert(afs_WriteDCache(adc, 1) == 0); + code = afs_WriteDCache(adc, 1); + if (code) { + ReleaseWriteLock(&afs_bufferLock); + return code; + } } ObtainWriteLock(&tb->lock, 265); tb->lockers++; -- 1.9.4