struct key *subtree; 
struct keyring_list *keylist; 
static int keyring_detect_cycle(struct key *A, struct key *B){	struct {		struct key *subtree;		int kix;	} stack[KEYRING_SEARCH_MAX_DEPTH];	struct keyring_list *keylist;	struct key *subtree, *key;	int sp, kix, ret;	ret = -EDEADLK;	if (A == B)		goto error;	subtree = B;	sp = 0;	/* start processing a new keyring */ descend:	read_lock(&subtree->lock);	if (subtree->flags & KEY_FLAG_REVOKED)		goto not_this_keyring;	keylist = subtree->payload.subscriptions;	if (!keylist)		goto not_this_keyring;	kix = 0; ascend:	/* iterate through the remaining keys in this keyring */	for (; kix < keylist->nkeys; kix++) {		key = keylist->keys[kix];		if (key == A)			goto cycle_detected;		/* recursively check nested keyrings */		if (key->type == &key_type_keyring) {			if (sp >= KEYRING_SEARCH_MAX_DEPTH)				goto too_deep;			/* stack the current position */			stack[sp].subtree = subtree;			stack[sp].kix = kix;			sp++;			/* begin again with the new keyring */			subtree = key;			goto descend;		}	}	/* the keyring we're looking at was disqualified or didn't contain a	 * matching key */ not_this_keyring:	read_unlock(&subtree->lock);	if (sp > 0) {		/* resume the checking of a keyring higher up in the tree */		sp--;		subtree = stack[sp].subtree;		keylist = subtree->payload.subscriptions;		kix = stack[sp].kix + 1;		goto ascend;	}	ret = 0; /* no cycles detected */ error:	return ret; too_deep:	ret = -ELOOP;	goto error_unwind; cycle_detected:	ret = -EDEADLK; error_unwind:	read_unlock(&subtree->lock);	/* unwind the keyring stack */	while (sp > 0) {		sp--;		read_unlock(&stack[sp].subtree->lock);	}	goto error;} /* end keyring_detect_cycle() */
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/76d8aeabfeb1c42641a81c44280177b9a08670d8/keyring.c/clean/security/keys/keyring.c