static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
	const struct in6_addr *psfsrc)
{
	struct ip6_sf_list *psf, *psf_prev;
	int rv = 0;

	psf_prev = NULL;
	for_each_psf_mclock(pmc, psf) {
		if (ipv6_addr_equal(&psf->sf_addr, psfsrc))
			break;
		psf_prev = psf;
	}
	if (!psf || psf->sf_count[sfmode] == 0) {
		/* source filter not found, or count wrong =>  bug */
		return -ESRCH;
	}
	psf->sf_count[sfmode]--;
	if (!psf->sf_count[MCAST_INCLUDE] && !psf->sf_count[MCAST_EXCLUDE]) {
		struct inet6_dev *idev = pmc->idev;

		/* no more filters for this source */
		if (psf_prev)
			rcu_assign_pointer(psf_prev->sf_next,
					   mc_dereference(psf->sf_next, idev));
		else
			rcu_assign_pointer(pmc->mca_sources,
					   mc_dereference(psf->sf_next, idev));

		if (psf->sf_oldin && !(pmc->mca_flags & MAF_NOREPORT) &&
		    !mld_in_v1_mode(idev)) {
			psf->sf_crcount = idev->mc_qrv;
			rcu_assign_pointer(psf->sf_next,
					   mc_dereference(pmc->mca_tomb, idev));
			rcu_assign_pointer(pmc->mca_tomb, psf);
			rv = 1;
		} else {
			kfree_rcu(psf, rcu);
		}
	}
	return rv;
}
static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
	const struct in6_addr *psfsrc)
{
	struct ip6_sf_list *psf, *psf_prev;
	int rv = 0;

	psf_prev = NULL;
	for_each_psf_mclock(pmc, psf) {
		if (ipv6_addr_equal(&psf->sf_addr, psfsrc))
			break;
		psf_prev = psf;
	}
	if (!psf || psf->sf_count[sfmode] == 0) {
		 
		return -ESRCH;
	}
	psf->sf_count[sfmode]--;
	if (!psf->sf_count[MCAST_INCLUDE] && !psf->sf_count[MCAST_EXCLUDE]) {
		struct inet6_dev *idev = pmc->idev;

		 
		if (psf_prev)
			rcu_assign_pointer(psf_prev->sf_next,
					   mc_dereference(psf->sf_next, idev));
		else
			rcu_assign_pointer(pmc->mca_sources,
					   mc_dereference(psf->sf_next, idev));

		if (psf->sf_oldin && !(pmc->mca_flags & MAF_NOREPORT) &&
		    !mld_in_v1_mode(idev)) {
			psf->sf_crcount = idev->mc_qrv;
			rcu_assign_pointer(psf->sf_next,
					   mc_dereference(pmc->mca_tomb, idev));
			rcu_assign_pointer(pmc->mca_tomb, psf);
			rv = 1;
		} else {
			kfree_rcu(psf, rcu);
		}
	}
	return rv;
}