PERFORCE change 38502 for review
Sam Leffler
sam at FreeBSD.org
Tue Sep 23 20:56:19 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=38502
Change 38502 by sam at sam_ebb on 2003/09/23 20:55:57
change explicit mtx operations to #defines to simplify
future changes to a different lock type
Affected files ...
.. //depot/projects/netperf/sys/netipsec/key.c#6 edit
Differences ...
==== //depot/projects/netperf/sys/netipsec/key.c#6 (text+ko) ====
@@ -125,15 +125,52 @@
static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD */
static struct mtx sptree_lock;
+#define SPTREE_LOCK_INIT() \
+ mtx_init(&sptree_lock, "sptree", \
+ "fast ipsec security policy database", MTX_DEF)
+#define SPTREE_LOCK_DESTROY() mtx_destroy(&sptree_lock)
+#define SPTREE_LOCK() mtx_lock(&sptree_lock)
+#define SPTREE_UNLOCK() mtx_unlock(&sptree_lock)
+#define SPTREE_LOCK_ASSERT() mtx_assert(&sptree_lock, MA_OWNED)
+
static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */
static struct mtx sahtree_lock;
+#define SAHTREE_LOCK_INIT() \
+ mtx_init(&sahtree_lock, "sahtree", \
+ "fast ipsec security association database", MTX_DEF)
+#define SAHTREE_LOCK_DESTROY() mtx_destroy(&sahtree_lock)
+#define SAHTREE_LOCK() mtx_lock(&sahtree_lock)
+#define SAHTREE_UNLOCK() mtx_unlock(&sahtree_lock)
+#define SAHTREE_LOCK_ASSERT() mtx_assert(&sahtree_lock, MA_OWNED)
+
/* registed list */
static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1];
static struct mtx regtree_lock;
+#define REGTREE_LOCK_INIT() \
+ mtx_init(®tree_lock, "regtree", "fast ipsec regtree", MTX_DEF)
+#define REGTREE_LOCK_DESTROY() mtx_destroy(®tree_lock)
+#define REGTREE_LOCK() mtx_lock(®tree_lock)
+#define REGTREE_UNLOCK() mtx_unlock(®tree_lock)
+#define REGTREE_LOCK_ASSERT() mtx_assert(®tree_lock, MA_OWNED)
+
static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */
static struct mtx acq_lock;
+#define ACQ_LOCK_INIT() \
+ mtx_init(&acq_lock, "acqtree", "fast ipsec acquire list", MTX_DEF)
+#define ACQ_LOCK_DESTROY() mtx_destroy(&acq_lock)
+#define ACQ_LOCK() mtx_lock(&acq_lock)
+#define ACQ_UNLOCK() mtx_unlock(&acq_lock)
+#define ACQ_LOCK_ASSERT() mtx_assert(&acq_lock, MA_OWNED)
+
static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */
static struct mtx spacq_lock;
+#define SPACQ_LOCK_INIT() \
+ mtx_init(&spacq_lock, "spacqtree", \
+ "fast ipsec security policy acquire list", MTX_DEF)
+#define SPACQ_LOCK_DESTROY() mtx_destroy(&spacq_lock)
+#define SPACQ_LOCK() mtx_lock(&spacq_lock)
+#define SPACQ_UNLOCK() mtx_unlock(&spacq_lock)
+#define SPACQ_LOCK_ASSERT() mtx_assert(&spacq_lock, MA_OWNED)
/* search order for SAs */
static u_int saorder_state_valid[] = {
@@ -517,7 +554,7 @@
printf("*** objects\n");
kdebug_secpolicyindex(spidx));
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
LIST_FOREACH(sp, &sptree[dir], chain) {
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** in SPD\n");
@@ -538,7 +575,7 @@
sp->lastused = time_second;
SP_ADDREF(sp);
}
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__,
@@ -574,7 +611,7 @@
printf("spi %u proto %u dir %u\n", spi, proto, dir);
kdebug_sockaddr(&dst->sa));
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
LIST_FOREACH(sp, &sptree[dir], chain) {
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** in SPD\n");
@@ -601,7 +638,7 @@
sp->lastused = time_second;
SP_ADDREF(sp);
}
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__,
@@ -635,7 +672,7 @@
goto done;
}
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
LIST_FOREACH(sp, &sptree[dir], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
@@ -677,7 +714,7 @@
sp->lastused = time_second;
SP_ADDREF(sp);
}
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
done:
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__,
@@ -792,16 +829,16 @@
struct secasvar *sav;
u_int stateidx, state;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) {
- mtx_unlock(&sahtree_lock); /* XXX??? */
+ SAHTREE_UNLOCK();
goto found;
}
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return NULL;
@@ -837,7 +874,7 @@
/* initilize */
candidate = NULL;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
for (sav = LIST_FIRST(&sah->savtree[state]);
sav != NULL;
sav = nextsav) {
@@ -944,7 +981,7 @@
printf("DP %s cause refcnt++:%d SA:%p\n",
__func__, candidate->refcnt, candidate));
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return candidate;
}
@@ -986,7 +1023,7 @@
* IPsec tunnel packet is received. But ESP tunnel mode is
* encrypted so we can't check internal IP header.
*/
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
/* search valid state */
for (stateidx = 0;
@@ -1019,7 +1056,7 @@
}
sav = NULL;
done:
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s return SA:%p; refcnt %u\n", __func__,
@@ -1038,7 +1075,7 @@
IPSEC_ASSERT(sp != NULL, ("null sp"));
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
SP_DELREF(sp);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
@@ -1049,7 +1086,7 @@
*spp = NULL;
key_delsp(sp);
}
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
}
/*
@@ -1153,7 +1190,7 @@
struct ipsecrequest *isr, *nextisr;
IPSEC_ASSERT(sp != NULL, ("null sp"));
- mtx_assert(&sptree_lock, MA_OWNED);
+ SPTREE_LOCK_ASSERT();
sp->state = IPSEC_SPSTATE_DEAD;
@@ -1188,7 +1225,7 @@
IPSEC_ASSERT(spidx != NULL, ("null spidx"));
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
LIST_FOREACH(sp, &sptree[spidx->dir], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
@@ -1197,7 +1234,7 @@
break;
}
}
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
return sp;
}
@@ -1212,7 +1249,7 @@
{
struct secpolicy *sp;
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
@@ -1231,7 +1268,7 @@
}
}
done:
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
return sp;
}
@@ -1833,7 +1870,7 @@
/* reset counter in order to deletion by timehandler. */
spacq->created = time_second;
spacq->count = 0;
- mtx_unlock(&spacq_lock);
+ SPACQ_UNLOCK();
}
}
@@ -2199,7 +2236,7 @@
newspacq->count++;
return 0;
}
- mtx_unlock(&spacq_lock);
+ SPACQ_UNLOCK();
} else {
/* make new entry for blocking to send SADB_ACQUIRE. */
newspacq = key_newspacq(&sp->spidx);
@@ -2558,9 +2595,9 @@
/* add to saidxtree */
newsah->state = SADB_SASTATE_MATURE;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_INSERT_HEAD(&sahtree, newsah, chain);
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
}
return(newsah);
}
@@ -2577,7 +2614,7 @@
int zombie = 0;
IPSEC_ASSERT(sah != NULL, ("NULL sah"));
- mtx_assert(&sahtree_lock, MA_OWNED);
+ SAHTREE_LOCK_ASSERT();
/* searching all SA registerd in the secindex. */
for (stateidx = 0;
@@ -2805,14 +2842,14 @@
{
struct secashead *sah;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID))
break;
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return sah;
}
@@ -2841,7 +2878,7 @@
sav = NULL;
/* check all SAD */
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
continue;
@@ -2849,7 +2886,7 @@
if (sav != NULL)
break;
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return sav;
}
@@ -2869,7 +2906,7 @@
u_int stateidx, state;
sav = NULL;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
/* search all status */
for (stateidx = 0;
stateidx < _ARRAYLEN(saorder_state_alive);
@@ -2890,7 +2927,7 @@
break;
}
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return sav;
}
@@ -3195,9 +3232,9 @@
break;
}
if (error == 0) {
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
key_sa_chgstate(sav, SADB_SASTATE_MATURE);
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
}
return (error);
}
@@ -3945,7 +3982,7 @@
/* SPD */
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
- mtx_lock(&sptree_lock);
+ SPTREE_LOCK();
for (sp = LIST_FIRST(&sptree[dir]);
sp != NULL;
sp = nextsp) {
@@ -3968,7 +4005,7 @@
continue;
}
}
- mtx_unlock(&sptree_lock);
+ SPTREE_UNLOCK();
}
}
@@ -3979,7 +4016,7 @@
struct secasvar *sav, *nextsav;
/* SAD */
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
for (sah = LIST_FIRST(&sahtree);
sah != NULL;
sah = nextsah) {
@@ -4134,7 +4171,7 @@
*/
}
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
}
static void
@@ -4143,7 +4180,7 @@
struct secacq *acq, *nextacq;
/* ACQ tree */
- mtx_lock(&acq_lock);
+ ACQ_LOCK();
for (acq = LIST_FIRST(&acqtree); acq != NULL; acq = nextacq) {
nextacq = LIST_NEXT(acq, chain);
if (now - acq->created > key_blockacq_lifetime
@@ -4152,7 +4189,7 @@
free(acq, M_IPSEC_SAQ);
}
}
- mtx_unlock(&acq_lock);
+ ACQ_UNLOCK();
}
static void
@@ -4161,7 +4198,7 @@
struct secspacq *acq, *nextacq;
/* SP ACQ tree */
- mtx_lock(&spacq_lock);
+ SPACQ_LOCK();
for (acq = LIST_FIRST(&spacqtree); acq != NULL; acq = nextacq) {
nextacq = LIST_NEXT(acq, chain);
if (now - acq->created > key_blockacq_lifetime
@@ -4170,7 +4207,7 @@
free(acq, M_IPSEC_SAQ);
}
}
- mtx_unlock(&spacq_lock);
+ SPACQ_UNLOCK();
}
/*
@@ -5062,7 +5099,7 @@
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
/* get a SA header */
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
@@ -5075,13 +5112,13 @@
break;
}
if (sah == NULL) {
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
ipseclog((LOG_DEBUG, "%s: no SA found.\n", __func__));
return key_senderror(so, m, ENOENT);
}
key_sa_chgstate(sav, SADB_SASTATE_DEAD);
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
KEY_FREESAV(&sav);
{
@@ -5130,7 +5167,7 @@
/* XXX boundary check against sa_len */
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
@@ -5160,7 +5197,7 @@
}
}
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
{
struct mbuf *n;
struct sadb_msg *newmsg;
@@ -5245,7 +5282,7 @@
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
/* get a SA header */
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
@@ -5257,7 +5294,7 @@
if (sav)
break;
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
if (sah == NULL) {
ipseclog((LOG_DEBUG, "%s: no SA found.\n", __func__));
return key_senderror(so, m, ENOENT);
@@ -5751,9 +5788,9 @@
newacq->count = 0;
/* add to acqtree */
- mtx_lock(&acq_lock);
+ ACQ_LOCK();
LIST_INSERT_HEAD(&acqtree, newacq, chain);
- mtx_unlock(&acq_lock);
+ ACQ_UNLOCK();
return newacq;
}
@@ -5763,12 +5800,12 @@
{
struct secacq *acq;
- mtx_lock(&acq_lock);
+ ACQ_LOCK();
LIST_FOREACH(acq, &acqtree, chain) {
if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY))
break;
}
- mtx_unlock(&acq_lock);
+ ACQ_UNLOCK();
return acq;
}
@@ -5779,12 +5816,12 @@
{
struct secacq *acq;
- mtx_lock(&acq_lock);
+ ACQ_LOCK();
LIST_FOREACH(acq, &acqtree, chain) {
if (acq->seq == seq)
break;
}
- mtx_unlock(&acq_lock);
+ ACQ_UNLOCK();
return acq;
}
@@ -5808,9 +5845,9 @@
acq->count = 0;
/* add to spacqtree */
- mtx_lock(&spacq_lock);
+ SPACQ_LOCK();
LIST_INSERT_HEAD(&spacqtree, acq, chain);
- mtx_unlock(&spacq_lock);
+ SPACQ_UNLOCK();
return acq;
}
@@ -5821,14 +5858,14 @@
{
struct secspacq *acq;
- mtx_lock(&spacq_lock);
+ SPACQ_LOCK();
LIST_FOREACH(acq, &spacqtree, chain) {
if (key_cmpspidx_exactly(spidx, &acq->spidx)) {
/* NB: return holding spacq_lock */
return acq;
}
}
- mtx_unlock(&spacq_lock);
+ SPACQ_UNLOCK();
return NULL;
}
@@ -5932,14 +5969,14 @@
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
/* get a SA index */
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID))
break;
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
if (sah != NULL) {
ipseclog((LOG_DEBUG, "%s: a SA exists already.\n", __func__));
return key_senderror(so, m, EEXIST);
@@ -5990,10 +6027,10 @@
goto setmsg;
/* check whether existing or not */
- mtx_lock(®tree_lock);
+ REGTREE_LOCK();
LIST_FOREACH(reg, ®tree[mhp->msg->sadb_msg_satype], chain) {
if (reg->so == so) {
- mtx_unlock(®tree_lock);
+ REGTREE_UNLOCK();
ipseclog((LOG_DEBUG, "%s: socket exists already.\n",
__func__));
return key_senderror(so, m, EEXIST);
@@ -6003,7 +6040,7 @@
/* create regnode */
newreg = malloc(sizeof(struct secreg), M_IPSEC_SAR, M_NOWAIT|M_ZERO);
if (newreg == NULL) {
- mtx_unlock(®tree_lock);
+ REGTREE_UNLOCK();
ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
return key_senderror(so, m, ENOBUFS);
}
@@ -6013,7 +6050,7 @@
/* add regnode to regtree. */
LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain);
- mtx_unlock(®tree_lock);
+ REGTREE_UNLOCK();
setmsg:
{
@@ -6138,7 +6175,7 @@
* check all type of SA, because there is a potential that
* one socket is registered to multiple type of SA.
*/
- mtx_lock(®tree_lock);
+ REGTREE_LOCK();
for (i = 0; i <= SADB_SATYPE_MAX; i++) {
LIST_FOREACH(reg, ®tree[i], chain) {
if (reg->so == so && __LIST_CHAINED(reg)) {
@@ -6148,7 +6185,7 @@
}
}
}
- mtx_unlock(®tree_lock);
+ REGTREE_UNLOCK();
}
/*
@@ -6313,7 +6350,7 @@
}
/* no SATYPE specified, i.e. flushing all SA. */
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
for (sah = LIST_FIRST(&sahtree);
sah != NULL;
sah = nextsah) {
@@ -6340,7 +6377,7 @@
sah->state = SADB_SASTATE_DEAD;
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
if (m->m_len < sizeof(struct sadb_msg) ||
sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
@@ -6401,7 +6438,7 @@
/* count sav entries to be sent to the userland. */
cnt = 0;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
&& proto != sah->saidx.proto)
@@ -6418,7 +6455,7 @@
}
if (cnt == 0) {
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return key_senderror(so, m, ENOENT);
}
@@ -6431,7 +6468,7 @@
/* map proto to satype */
if ((satype = key_proto2satype(sah->saidx.proto)) == 0) {
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
ipseclog((LOG_DEBUG, "%s: there was invalid proto in "
"SAD.\n", __func__));
return key_senderror(so, m, EINVAL);
@@ -6445,14 +6482,14 @@
n = key_setdumpsa(sav, SADB_DUMP, satype,
--cnt, mhp->msg->sadb_msg_pid);
if (!n) {
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
return key_senderror(so, m, ENOBUFS);
}
key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
}
}
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
m_freem(m);
return 0;
@@ -6993,11 +7030,11 @@
{
int i;
- mtx_init(&sptree_lock, "sptree lock", "fast ipsec sadb", MTX_DEF);
- mtx_init(®tree_lock, "regtree lock", "fast ipsec sadb", MTX_DEF);
- mtx_init(&sahtree_lock, "sahtree lock", "fast ipsec sadb", MTX_DEF);
- mtx_init(&acq_lock, "acqtree lock", "fast ipsec sadb", MTX_DEF);
- mtx_init(&spacq_lock, "spacqtree lock", "fast ipsec sadb", MTX_DEF);
+ SPTREE_LOCK_INIT();
+ REGTREE_LOCK_INIT();
+ SAHTREE_LOCK_INIT();
+ ACQ_LOCK_INIT();
+ SPACQ_LOCK_INIT();
for (i = 0; i < IPSEC_DIR_MAX; i++)
LIST_INIT(&sptree[i]);
@@ -7099,7 +7136,7 @@
struct secashead *sah;
struct route *ro;
- mtx_lock(&sahtree_lock);
+ SAHTREE_LOCK();
LIST_FOREACH(sah, &sahtree, chain) {
ro = &sah->sa_route;
if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
@@ -7108,7 +7145,7 @@
ro->ro_rt = (struct rtentry *)NULL;
}
}
- mtx_unlock(&sahtree_lock);
+ SAHTREE_UNLOCK();
}
static void
@@ -7117,7 +7154,7 @@
u_int8_t state;
{
IPSEC_ASSERT(sav != NULL, ("NULL sav"));
- mtx_assert(&sahtree_lock, MA_OWNED);
+ SAHTREE_LOCK_ASSERT();
if (sav->state != state) {
if (__LIST_CHAINED(sav))
More information about the p4-projects
mailing list