From cfd5d1461e6fa28ab277575991d5f8eda3e46ce0 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 27 Apr 2011 14:23:43 -0500 Subject: [PATCH] viced: Avoid ref leak on origin callback break When breaking a callback, sometimes we send a callback to the host that performed the callback-inducing operation. When we do this, currently BreakCallBack gives the origin host structure to MultiBreakCallBack_r, which avoids releasing that host after the callback is broken. However, BreakCallBack obtains a reference to every host to which it delivers a callback, even if it is the origin host, so a reference is leaked. Fix this by not ever passing a host to MultiBreakCallBack_r, and just have MultiBreakCallBack_r release a reference for every host to which it delivers a callback break. FIXES 129376 Reviewed-on: http://gerrit.openafs.org/4581 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit af175ce2c7a4785ef1992d096adfdb27daa86ee4) Change-Id: Ifd59c8ce93939f7b23e9f64bd7c0e527d3a2fa52 Reviewed-on: http://gerrit.openafs.org/4592 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/viced/callback.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/viced/callback.c b/src/viced/callback.c index fdbd5b55c..e7d85fa8c 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -190,7 +190,7 @@ static int FDel(struct FileEntry *fe); static int AddCallBack1_r(struct host *host, AFSFid * fid, afs_uint32 * thead, int type, int locked); static void MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, - struct AFSCBFids *afidp, struct host *xhost); + struct AFSCBFids *afidp); static int MultiBreakVolumeCallBack_r(struct host *host, struct VCBParams *parms, int deletefe); static int MultiBreakVolumeLaterCallBack(struct host *host, void *rock); @@ -667,8 +667,8 @@ CompareCBA(const void *e1, const void *e2) } /* Take an array full of hosts, all held. Break callbacks to them, and - * release the holds once you're done, except don't release xhost. xhost - * may be NULL. Currently only works for a single Fid in afidp array. + * release the holds once you're done. + * Currently only works for a single Fid in afidp array. * If you want to make this work with multiple fids, you need to fix * the error handling. One approach would be to force a reset if a * multi-fid call fails, or you could add delayed callbacks for each @@ -686,7 +686,7 @@ CompareCBA(const void *e1, const void *e2) * wherever that is done. */ static void MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, - struct AFSCBFids *afidp, struct host *xhost) + struct AFSCBFids *afidp) { int i, j; struct rx_connection *conns[MAX_CB_HOSTS]; @@ -773,7 +773,7 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, for (i = 0; i < ncbas; i++) { struct host *hp; hp = cba[i].hp; - if (hp && xhost != hp) { + if (hp) { h_Release_r(hp); } } @@ -863,7 +863,7 @@ BreakCallBack(struct host *xhost, AFSFid * fid, int flag) } if (ncbas) { - MultiBreakCallBack_r(cba, ncbas, &tf, xhost); + MultiBreakCallBack_r(cba, ncbas, &tf); /* we need to to all these initializations again because MultiBreakCallBack may block */ fe = FindFE(fid); @@ -1154,7 +1154,7 @@ MultiBreakVolumeCallBack_r(struct host *host, tf.AFSCBFids_val = parms->fid; /* this releases all the hosts */ - MultiBreakCallBack_r(parms->cba, parms->ncbas, &tf, 0 /* xhost */ ); + MultiBreakCallBack_r(parms->cba, parms->ncbas, &tf); parms->ncbas = 0; } @@ -1336,7 +1336,7 @@ BreakLaterCallBacks(void) tf.AFSCBFids_len = 1; tf.AFSCBFids_val = &fid; - MultiBreakCallBack_r(henumParms.cba, henumParms.ncbas, &tf, 0); + MultiBreakCallBack_r(henumParms.cba, henumParms.ncbas, &tf); henumParms.ncbas = 0; } } -- 2.39.5