Currently, we free our CBR structures in shutdown_vcache, but later on
in shutdown_server, we call afs_FreeCBR on each one that's attached to
a struct server. afs_FreeCBR doesn't actually free the memory; it just
modifies some pointers to put the CBR on the free list. Since we do
this after the underlying memory has been freed, it can cause a panic
during shutdown since the structures are no longer valid.
To avoid this, make the afs_FreeCBR calls inside shutdown_vcache,
right before the memory is freed.
Change-Id: I142126d6aa811762b6c234d05abdac3764dad887
Reviewed-on: https://gerrit.openafs.org/14165
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
shutdown_server(void)
{
int i;
- struct afs_cbr *tcbrp, *tbrp;
struct srvAddr *sa;
for (i = 0; i < NSERVERS; i++) {
afs_ReleaseConns(sa->conns);
}
}
- for (tcbrp = ts->cbrs; tcbrp; tcbrp = tbrp) {
- /*
- * Free all server's callback structs
- */
- tbrp = tcbrp->next;
- afs_FreeCBR(tcbrp);
- }
afs_osi_Free(ts, sizeof(struct server));
ts = next;
}
{
int i;
struct afs_cbr *tsp;
+ struct afs_cbr *cbr, *cbr_next;
+ struct server *ts;
+
/*
* XXX We may potentially miss some of the vcaches because if when
* there are no free vcache entries and all the vcache entries are active
afs_vhashT[i] = 0;
}
}
+
+ /*
+ * Remove any reference to CBRs in the server structs before we free the
+ * memory for our CBRs below.
+ */
+ for (i = 0; i < NSERVERS; i++) {
+ for (ts = afs_servers[i]; ts; ts = ts->next) {
+ for (cbr = ts->cbrs; cbr; cbr = cbr_next) {
+ cbr_next = cbr->next;
+ afs_FreeCBR(cbr);
+ }
+ }
+ }
+
/*
* Free any leftover callback queue
*/