afs: Handle osi_NewVnode failures 01/13701/8
authorAndrew Deason <adeason@sinenomine.net>
Thu, 18 Jul 2019 21:21:10 +0000 (16:21 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 23 Oct 2020 16:43:48 +0000 (12:43 -0400)
Currently, code inside afs_vcache.c assumes that osi_NewVnode always
returns non-NULL, which means that osi_NewVnode must panic if it
cannot create a new vnode.

All of the callers of afs_GetVCache, afs_NewVCache, etc, already
handle getting a NULL return, though (after all, the given fid may not
exist or be inaccessible due to network errors, etc). So, just
propagate NULL returns from osi_NewVnode up to our callers, to avoid
panics in these situations.

Modify osi_NewVnode on many arches to return an error on allocation
failure, instead of panic'ing.

Change-Id: Ib578b1747590bdf65327d4674e0849811ed999eb
Reviewed-on: https://gerrit.openafs.org/13701
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Yadavendra Yadav <yadayada@in.ibm.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/AIX/osi_vcache.c
src/afs/DARWIN/osi_vcache.c
src/afs/FBSD/osi_vcache.c
src/afs/IRIX/osi_vcache.c
src/afs/LINUX/osi_vcache.c
src/afs/NBSD/osi_vcache.c
src/afs/OBSD/osi_vcache.c
src/afs/SOLARIS/osi_vcache.c
src/afs/afs_vcache.c

index eec57c9..351afbb 100644 (file)
@@ -34,7 +34,9 @@ osi_NewVnode(void)
     struct vcache *tvc;
 
     tvc = afs_osi_Alloc(sizeof(struct vcache));
-    osi_Assert(tvc != NULL);
+    if (tvc == NULL) {
+       return NULL;
+    }
 
 #ifdef KERNEL_HAVE_PIN
     pin((char *)tvc, sizeof(struct vcache));   /* XXX */
index 1d79224..26493e6 100644 (file)
@@ -19,7 +19,9 @@ osi_NewVnode(void)
     struct vcache *tvc;
 
     tvc = afs_osi_Alloc(sizeof(struct vcache));
-    osi_Assert(tvc != NULL);
+    if (tvc == NULL) {
+       return NULL;
+    }
     tvc->v = NULL; /* important to clean this, or use memset 0 */
 
     return tvc;
index 922d8c1..22ca8d4 100644 (file)
@@ -70,6 +70,9 @@ osi_NewVnode(void)
     struct vcache *tvc;
 
     tvc = afs_osi_Alloc(sizeof(struct vcache));
+    if (tvc == NULL) {
+       return NULL;
+    }
     tvc->v = NULL; /* important to clean this, or use memset 0 */
 
     return tvc;
index 522e8b5..5d1cea2 100644 (file)
@@ -36,6 +36,9 @@ osi_NewVnode(void)
     char name[METER_NAMSZ];
 
     avc = afs_osi_Alloc(sizeof(struct vcache));
+    if (avc == NULL) {
+       return NULL;
+    }
 
     memset(avc, 0, sizeof(struct vcache));
     avc->v.v_number = ++afsvnumbers;
index e3be81a..0d810b1 100644 (file)
@@ -146,13 +146,18 @@ osi_NewVnode(void)
 
     AFS_GUNLOCK();
     ip = new_inode(afs_globalVFS);
-    if (!ip)
-       osi_Panic("afs_NewVCache: no more inodes");
     AFS_GLOCK();
+    if (ip == NULL) {
+       return NULL;
+    }
 #if defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)
     tvc = VTOAFS(ip);
 #else
     tvc = afs_osi_Alloc(sizeof(struct vcache));
+    if (tvc == NULL) {
+       iput(ip);
+       return NULL;
+    }
     ip->u.generic_ip = tvc;
     tvc->v = ip;
 #endif
index 2f99075..5be3e1d 100644 (file)
@@ -43,6 +43,9 @@ osi_NewVnode(void)
     struct vcache *tvc;
 
     tvc = afs_osi_Alloc(sizeof(struct vcache));
+    if (tvc == NULL) {
+       return NULL;
+    }
     tvc->v = NULL; /* important to clean this, or use memset 0 */
 
     return tvc;
index 2798a5f..07416b1 100644 (file)
@@ -40,6 +40,9 @@ osi_NewVnode(void)
     struct vcache *tvc;
 
     tvc = afs_osi_Alloc(sizeof(struct vcache));
+    if (tvc == NULL) {
+       return NULL;
+    }
     tvc->v = NULL; /* important to clean this, or use memset 0 */
 
     return tvc;
index 7f0b9f6..e3cb9a4 100644 (file)
@@ -33,7 +33,9 @@ osi_NewVnode(void)
     struct vcache *avc;
 
     avc = afs_osi_Alloc(sizeof(struct vcache));
-    osi_Assert(avc != NULL);
+    if (avc == NULL) {
+       return NULL;
+    }
     return avc;
 }
 
index 407e5a6..465aa98 100644 (file)
@@ -917,6 +917,9 @@ afs_AllocVCache(void)
     struct vcache *tvc;
 
     tvc = osi_NewVnode();
+    if (tvc == NULL) {
+       return NULL;
+    }
 
     afs_vcount++;
 
@@ -1050,6 +1053,9 @@ afs_NewVCache_int(struct VenusFid *afid, struct server *serverp, int seq)
        }
     }
     tvc = afs_AllocVCache();
+    if (tvc == NULL) {
+       return NULL;
+    }
 #else /* AFS_LINUX22_ENV */
     /* pull out a free cache entry */
     if (!freeVCList) {
@@ -1058,6 +1064,9 @@ afs_NewVCache_int(struct VenusFid *afid, struct server *serverp, int seq)
 
     if (!freeVCList) {
        tvc = afs_AllocVCache();
+       if (tvc == NULL) {
+           return NULL;
+       }
     } else {
        tvc = freeVCList;       /* take from free list */
        freeVCList = tvc->nextfree;