From 932347ddb95eca41ee4365b8ea32d282c692eaba Mon Sep 17 00:00:00 2001 From: Cheyenne Wills Date: Thu, 2 Jul 2020 13:39:27 -0600 Subject: [PATCH 09/12] LINUX: Don't panic on some file open errors Commit 'LINUX: Return NULL for afs_linux_raw_open error' (f6af4a155) updated afs_linux_raw_open to return NULL on some errors, but still panics if obtaining the dentry fails. Commit 'afs: Verify osi_UFSOpen worked' (c6b61a451) updated callers of osi_UFSOpen to verify whether or not the open was successful. This meant osi_UFSOpen (and routines it calls) could pass back an error indication rather than panic when an error is encountered. Update afs_linux_raw_open to return a failure instead of panic if unable to obtain a dentry. Update osi_UFSOpen to return a NULL instead of panic if unable to obtain memory or fails to open the file. All callers of osi_UFSOpen handle a fail return, though some will still issue a panic. Update afs_linux_readpage_fastpath and afs_linux_readpages to not panic if afs_linux_raw_open fails. Instead of panic, return an error. For testing, an error can be forced by removing a file from the cache directory. Note this work is based on a commit by pruiter@sinenomine.net Change-Id: Ic47e4868b4f81d99fbe3b2e4958778508ae4851f Reviewed-on: https://gerrit.openafs.org/14242 Reviewed-by: Andrew Deason Reviewed-by: Mark Vitale Reviewed-by: Benjamin Kaduk Tested-by: BuildBot (cherry picked from commit af73b9a3b1fc625694807287c0897391feaad52d) --- src/afs/LINUX/osi_file.c | 15 +++++++++++---- src/afs/LINUX/osi_vnodeops.c | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index 03777f563..004799c4c 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -65,8 +65,12 @@ afs_linux_raw_open(afs_dcache_id_t *ainode) dp = afs_get_dentry_from_fh(afs_cacheSBp, ainode, cache_fh_len, cache_fh_type, afs_fh_acceptable); - if ((!dp) || IS_ERR(dp)) - osi_Panic("Can't get dentry\n"); + if ((!dp) || IS_ERR(dp)) { + afs_warn("afs: Cannot get dentry for cache file (code %d). Trying to continue, " + "but AFS accesses may return errors or panic the system\n", + (int) PTR_ERR(dp)); + return NULL; + } tip = dp->d_inode; tip->i_flags |= S_NOATIME; /* Disable updating access times. */ @@ -115,8 +119,11 @@ osi_UFSOpen(afs_dcache_id_t *ainode) AFS_GUNLOCK(); afile = kmalloc(sizeof(struct osi_file), GFP_NOFS); if (!afile) { - osi_Panic("osi_UFSOpen: Failed to allocate %d bytes for osi_file.\n", - (int)sizeof(struct osi_file)); + afs_warn("afs: Failed to allocate memory for opening a cache file. " + "Trying to continue, but AFS access may return errors or panic " + "the system\n"); + AFS_GLOCK(); + return NULL; } memset(afile, 0, sizeof(struct osi_file)); diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 9b5d05471..1631d3d3d 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -2398,7 +2398,11 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep) /* XXX - I suspect we should be locking the inodes before we use them! */ AFS_GUNLOCK(); cacheFp = afs_linux_raw_open(&tdc->f.inode); - osi_Assert(cacheFp); + if (cacheFp == NULL) { + /* Problem getting the inode */ + AFS_GLOCK(); + goto out; + } if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) { cachefs_noreadpage = 1; AFS_GLOCK(); @@ -2785,8 +2789,10 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, afs_PutDCache(tdc); AFS_GUNLOCK(); tdc = NULL; - if (cacheFp) + if (cacheFp) { filp_close(cacheFp, NULL); + cacheFp = NULL; + } } if (!tdc) { @@ -2803,7 +2809,10 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, AFS_GUNLOCK(); if (tdc) { cacheFp = afs_linux_raw_open(&tdc->f.inode); - osi_Assert(cacheFp); + if (cacheFp == NULL) { + /* Problem getting the inode */ + goto out; + } if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) { cachefs_noreadpage = 1; goto out; @@ -2824,7 +2833,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, afs_lru_cache_finalize(&lrupages); out: - if (tdc) + if (cacheFp) filp_close(cacheFp, NULL); afs_pagecopy_put_task(task); -- 2.36.1