ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
{
	struct ieee80211_local *local = rx->local;
	struct ieee80211_sub_if_data *sdata = rx->sdata;
	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
	int len = rx->skb->len;

	if (!ieee80211_is_action(mgmt->frame_control))
		return RX_CONTINUE;

	/* drop too small frames */
	if (len < IEEE80211_MIN_ACTION_SIZE)
		return RX_DROP_UNUSABLE;

	if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
	    mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED &&
	    mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT)
		return RX_DROP_UNUSABLE;

	switch (mgmt->u.action.category) {
	case WLAN_CATEGORY_HT:
		/* reject HT action frames from stations not supporting HT */
		if (!rx->sta->sta.ht_cap.ht_supported)
			goto invalid;

		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
		    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
		    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
		    sdata->vif.type != NL80211_IFTYPE_AP &&
		    sdata->vif.type != NL80211_IFTYPE_ADHOC)
			break;

		/* verify action & smps_control/chanwidth are present */
		if (len < IEEE80211_MIN_ACTION_SIZE + 2)
			goto invalid;

		switch (mgmt->u.action.u.ht_smps.action) {
		case WLAN_HT_ACTION_SMPS: {
			struct ieee80211_supported_band *sband;
			enum ieee80211_smps_mode smps_mode;
			struct sta_opmode_info sta_opmode = {};

			/* convert to HT capability */
			switch (mgmt->u.action.u.ht_smps.smps_control) {
			case WLAN_HT_SMPS_CONTROL_DISABLED:
				smps_mode = IEEE80211_SMPS_OFF;
				break;
			case WLAN_HT_SMPS_CONTROL_STATIC:
				smps_mode = IEEE80211_SMPS_STATIC;
				break;
			case WLAN_HT_SMPS_CONTROL_DYNAMIC:
				smps_mode = IEEE80211_SMPS_DYNAMIC;
				break;
			default:
				goto invalid;
			}

			/* if no change do nothing */
			if (rx->sta->sta.smps_mode == smps_mode)
				goto handled;
			rx->sta->sta.smps_mode = smps_mode;
			sta_opmode.smps_mode =
				ieee80211_smps_mode_to_smps_mode(smps_mode);
			sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED;

			sband = rx->local->hw.wiphy->bands[status->band];

			rate_control_rate_update(local, sband, rx->sta,
						 IEEE80211_RC_SMPS_CHANGED);
			cfg80211_sta_opmode_change_notify(sdata->dev,
							  rx->sta->addr,
							  &sta_opmode,
							  GFP_ATOMIC);
			goto handled;
		}
		case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
			struct ieee80211_supported_band *sband;
			u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
			enum ieee80211_sta_rx_bandwidth max_bw, new_bw;
			struct sta_opmode_info sta_opmode = {};

			/* If it doesn't support 40 MHz it can't change ... */
			if (!(rx->sta->sta.ht_cap.cap &
					IEEE80211_HT_CAP_SUP_WIDTH_20_40))
				goto handled;

			if (chanwidth == IEEE80211_HT_CHANWIDTH_20MHZ)
				max_bw = IEEE80211_STA_RX_BW_20;
			else
				max_bw = ieee80211_sta_cap_rx_bw(rx->sta);

			/* set cur_max_bandwidth and recalc sta bw */
			rx->sta->cur_max_bandwidth = max_bw;
			new_bw = ieee80211_sta_cur_vht_bw(rx->sta);

			if (rx->sta->sta.bandwidth == new_bw)
				goto handled;

			rx->sta->sta.bandwidth = new_bw;
			sband = rx->local->hw.wiphy->bands[status->band];
			sta_opmode.bw =
				ieee80211_sta_rx_bw_to_chan_width(rx->sta);
			sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED;

			rate_control_rate_update(local, sband, rx->sta,
						 IEEE80211_RC_BW_CHANGED);
			cfg80211_sta_opmode_change_notify(sdata->dev,
							  rx->sta->addr,
							  &sta_opmode,
							  GFP_ATOMIC);
			goto handled;
		}
		default:
			goto invalid;
		}

		break;
	case WLAN_CATEGORY_PUBLIC:
		if (len < IEEE80211_MIN_ACTION_SIZE + 1)
			goto invalid;
		if (sdata->vif.type != NL80211_IFTYPE_STATION)
			break;
		if (!rx->sta)
			break;
		if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid))
			break;
		if (mgmt->u.action.u.ext_chan_switch.action_code !=
				WLAN_PUB_ACTION_EXT_CHANSW_ANN)
			break;
		if (len < offsetof(struct ieee80211_mgmt,
				   u.action.u.ext_chan_switch.variable))
			goto invalid;
		goto queue;
	case WLAN_CATEGORY_VHT:
		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
		    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
		    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
		    sdata->vif.type != NL80211_IFTYPE_AP &&
		    sdata->vif.type != NL80211_IFTYPE_ADHOC)
			break;

		/* verify action code is present */
		if (len < IEEE80211_MIN_ACTION_SIZE + 1)
			goto invalid;

		switch (mgmt->u.action.u.vht_opmode_notif.action_code) {
		case WLAN_VHT_ACTION_OPMODE_NOTIF: {
			/* verify opmode is present */
			if (len < IEEE80211_MIN_ACTION_SIZE + 2)
				goto invalid;
			goto queue;
		}
		case WLAN_VHT_ACTION_GROUPID_MGMT: {
			if (len < IEEE80211_MIN_ACTION_SIZE + 25)
				goto invalid;
			goto queue;
		}
		default:
			break;
		}
		break;
	case WLAN_CATEGORY_BACK:
		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
		    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
		    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
		    sdata->vif.type != NL80211_IFTYPE_AP &&
		    sdata->vif.type != NL80211_IFTYPE_ADHOC)
			break;

		/* verify action_code is present */
		if (len < IEEE80211_MIN_ACTION_SIZE + 1)
			break;

		switch (mgmt->u.action.u.addba_req.action_code) {
		case WLAN_ACTION_ADDBA_REQ:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.addba_req)))
				goto invalid;
			break;
		case WLAN_ACTION_ADDBA_RESP:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.addba_resp)))
				goto invalid;
			break;
		case WLAN_ACTION_DELBA:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.delba)))
				goto invalid;
			break;
		default:
			goto invalid;
		}

		goto queue;
	case WLAN_CATEGORY_SPECTRUM_MGMT:
		/* verify action_code is present */
		if (len < IEEE80211_MIN_ACTION_SIZE + 1)
			break;

		switch (mgmt->u.action.u.measurement.action_code) {
		case WLAN_ACTION_SPCT_MSR_REQ:
			if (status->band != NL80211_BAND_5GHZ)
				break;

			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.measurement)))
				break;

			if (sdata->vif.type != NL80211_IFTYPE_STATION)
				break;

			ieee80211_process_measurement_req(sdata, mgmt, len);
			goto handled;
		case WLAN_ACTION_SPCT_CHL_SWITCH: {
			u8 *bssid;
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.chan_switch)))
				break;

			if (sdata->vif.type != NL80211_IFTYPE_STATION &&
			    sdata->vif.type != NL80211_IFTYPE_ADHOC &&
			    sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
				break;

			if (sdata->vif.type == NL80211_IFTYPE_STATION)
				bssid = sdata->u.mgd.bssid;
			else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
				bssid = sdata->u.ibss.bssid;
			else if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
				bssid = mgmt->sa;
			else
				break;

			if (!ether_addr_equal(mgmt->bssid, bssid))
				break;

			goto queue;
			}
		}
		break;
	case WLAN_CATEGORY_SA_QUERY:
		if (len < (IEEE80211_MIN_ACTION_SIZE +
			   sizeof(mgmt->u.action.u.sa_query)))
			break;

		switch (mgmt->u.action.u.sa_query.action) {
		case WLAN_ACTION_SA_QUERY_REQUEST:
			if (sdata->vif.type != NL80211_IFTYPE_STATION)
				break;
			ieee80211_process_sa_query_req(sdata, mgmt, len);
			goto handled;
		}
		break;
	case WLAN_CATEGORY_SELF_PROTECTED:
		if (len < (IEEE80211_MIN_ACTION_SIZE +
			   sizeof(mgmt->u.action.u.self_prot.action_code)))
			break;

		switch (mgmt->u.action.u.self_prot.action_code) {
		case WLAN_SP_MESH_PEERING_OPEN:
		case WLAN_SP_MESH_PEERING_CLOSE:
		case WLAN_SP_MESH_PEERING_CONFIRM:
			if (!ieee80211_vif_is_mesh(&sdata->vif))
				goto invalid;
			if (sdata->u.mesh.user_mpm)
				/* userspace handles this frame */
				break;
			goto queue;
		case WLAN_SP_MGK_INFORM:
		case WLAN_SP_MGK_ACK:
			if (!ieee80211_vif_is_mesh(&sdata->vif))
				goto invalid;
			break;
		}
		break;
	case WLAN_CATEGORY_MESH_ACTION:
		if (len < (IEEE80211_MIN_ACTION_SIZE +
			   sizeof(mgmt->u.action.u.mesh_action.action_code)))
			break;

		if (!ieee80211_vif_is_mesh(&sdata->vif))
			break;
		if (mesh_action_is_path_sel(mgmt) &&
		    !mesh_path_sel_is_hwmp(sdata))
			break;
		goto queue;
	}

	return RX_CONTINUE;

 invalid:
	status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM;
	/* will return in the next handlers */
	return RX_CONTINUE;

 handled:
	if (rx->sta)
		rx->sta->rx_stats.packets++;
	dev_kfree_skb(rx->skb);
	return RX_QUEUED;

 queue:
	skb_queue_tail(&sdata->skb_queue, rx->skb);
	ieee80211_queue_work(&local->hw, &sdata->work);
	if (rx->sta)
		rx->sta->rx_stats.packets++;
	return RX_QUEUED;
}


static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
	int tid, seqno_idx, security_idx;

	/* does the frame have a qos control field? */
	if (ieee80211_is_data_qos(hdr->frame_control)) {
		u8 *qc = ieee80211_get_qos_ctl(hdr);
		/* frame has qos control */
		tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
		if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
			status->rx_flags |= IEEE80211_RX_AMSDU;

		seqno_idx = tid;
		security_idx = tid;
	} else {
		/*
		 * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"):
		 *
		 *	Sequence numbers for management frames, QoS data
		 *	frames with a broadcast/multicast address in the
		 *	Address 1 field, and all non-QoS data frames sent
		 *	by QoS STAs are assigned using an additional single
		 *	modulo-4096 counter, [...]
		 *
		 * We also use that counter for non-QoS STAs.
		 */
		seqno_idx = IEEE80211_NUM_TIDS;
		security_idx = 0;
		if (ieee80211_is_mgmt(hdr->frame_control))
			security_idx = IEEE80211_NUM_TIDS;
		tid = 0;
	}

	rx->seqno_idx = seqno_idx;
	rx->security_idx = security_idx;
	/* Set skb->priority to 1d tag if highest order bit of TID is not set.
	 * For now, set skb->priority to 0 for other cases. */
	rx->skb->priority = (tid > 7) ? 0 : tid;
}


static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
					    struct tid_ampdu_rx *tid_agg_rx,
					    int index,
					    struct sk_buff_head *frames)
{
	struct sk_buff_head *skb_list = &tid_agg_rx->reorder_buf[index];
	struct sk_buff *skb;
	struct ieee80211_rx_status *status;

	lockdep_assert_held(&tid_agg_rx->reorder_lock);

	if (skb_queue_empty(skb_list))
		goto no_frame;

	if (!ieee80211_rx_reorder_ready(tid_agg_rx, index)) {
		__skb_queue_purge(skb_list);
		goto no_frame;
	}

	/* release frames from the reorder ring buffer */
	tid_agg_rx->stored_mpdu_num--;
	while ((skb = __skb_dequeue(skb_list))) {
		status = IEEE80211_SKB_RXCB(skb);
		status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
		__skb_queue_tail(frames, skb);
	}

no_frame:
	tid_agg_rx->reorder_buf_filtered &= ~BIT_ULL(index);
	tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num);
}


static u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
			       enum nl80211_iftype type)
{
	__le16 fc = hdr->frame_control;

	if (ieee80211_is_data(fc)) {
		if (len < 24) /* drop incorrect hdr len (data) */
			return NULL;

		if (ieee80211_has_a4(fc))
			return NULL;
		if (ieee80211_has_tods(fc))
			return hdr->addr1;
		if (ieee80211_has_fromds(fc))
			return hdr->addr2;

		return hdr->addr3;
	}

	if (ieee80211_is_mgmt(fc)) {
		if (len < 24) /* drop incorrect hdr len (mgmt) */
			return NULL;
		return hdr->addr3;
	}

	if (ieee80211_is_ctl(fc)) {
		if (ieee80211_is_pspoll(fc))
			return hdr->addr1;

		if (ieee80211_is_back_req(fc)) {
			switch (type) {
			case NL80211_IFTYPE_STATION:
				return hdr->addr2;
			case NL80211_IFTYPE_AP:
			case NL80211_IFTYPE_AP_VLAN:
				return hdr->addr1;
			default:
				break; /* fall through to the return */
			}
		}
	}

	return NULL;
}


static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
{
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);

	/*
	 * Pass through unencrypted frames if the hardware has
	 * decrypted them already.
	 */
	if (status->flag & RX_FLAG_DECRYPTED)
		return 0;

	/* Drop unencrypted frames if key is set. */
	if (unlikely(!ieee80211_has_protected(fc) &&
		     !ieee80211_is_nullfunc(fc) &&
		     ieee80211_is_data(fc) && rx->key))
		return -EACCES;

	return 0;
}


static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
					 struct ieee80211_sta *pubsta,
					 struct sk_buff *skb,
					 struct napi_struct *napi)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_hdr *hdr;
	__le16 fc;
	struct ieee80211_rx_data rx;
	struct ieee80211_sub_if_data *prev;
	struct rhlist_head *tmp;
	int err = 0;

	fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
	memset(&rx, 0, sizeof(rx));
	rx.skb = skb;
	rx.local = local;
	rx.napi = napi;

	if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
		I802_DEBUG_INC(local->dot11ReceivedFragmentCount);

	if (ieee80211_is_mgmt(fc)) {
		/* drop frame if too short for header */
		if (skb->len < ieee80211_hdrlen(fc))
			err = -ENOBUFS;
		else
			err = skb_linearize(skb);
	} else {
		err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
	}

	if (err) {
		dev_kfree_skb(skb);
		return;
	}

	hdr = (struct ieee80211_hdr *)skb->data;
	ieee80211_parse_qos(&rx);
	ieee80211_verify_alignment(&rx);

	if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) ||
		     ieee80211_is_beacon(hdr->frame_control)))
		ieee80211_scan_rx(local, skb);

	if (ieee80211_is_data(fc)) {
		struct sta_info *sta, *prev_sta;

		if (pubsta) {
			rx.sta = container_of(pubsta, struct sta_info, sta);
			rx.sdata = rx.sta->sdata;
			if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
				return;
			goto out;
		}

		prev_sta = NULL;

		for_each_sta_info(local, hdr->addr2, sta, tmp) {
			if (!prev_sta) {
				prev_sta = sta;
				continue;
			}

			rx.sta = prev_sta;
			rx.sdata = prev_sta->sdata;
			ieee80211_prepare_and_rx_handle(&rx, skb, false);

			prev_sta = sta;
		}

		if (prev_sta) {
			rx.sta = prev_sta;
			rx.sdata = prev_sta->sdata;

			if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
				return;
			goto out;
		}
	}

	prev = NULL;

	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
		if (!ieee80211_sdata_running(sdata))
			continue;

		if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
		    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
			continue;

		/*
		 * frame is destined for this interface, but if it's
		 * not also for the previous one we handle that after
		 * the loop to avoid copying the SKB once too much
		 */

		if (!prev) {
			prev = sdata;
			continue;
		}

		rx.sta = sta_info_get_bss(prev, hdr->addr2);
		rx.sdata = prev;
		ieee80211_prepare_and_rx_handle(&rx, skb, false);

		prev = sdata;
	}

	if (prev) {
		rx.sta = sta_info_get_bss(prev, hdr->addr2);
		rx.sdata = prev;

		if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
			return;
	}

 out:
	dev_kfree_skb(skb);
}


void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
{
	struct sk_buff_head frames;
	struct ieee80211_rx_data rx = {
		.sta = sta,
		.sdata = sta->sdata,
		.local = sta->local,
		/* This is OK -- must be QoS data frame */
		.security_idx = tid,
		.seqno_idx = tid,
		.napi = NULL, /* must be NULL to not have races */
	};
	struct tid_ampdu_rx *tid_agg_rx;

	tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
	if (!tid_agg_rx)
		return;

	__skb_queue_head_init(&frames);

	spin_lock(&tid_agg_rx->reorder_lock);
	ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx, &frames);
	spin_unlock(&tid_agg_rx->reorder_lock);

	if (!skb_queue_empty(&frames)) {
		struct ieee80211_event event = {
			.type = BA_FRAME_TIMEOUT,
			.u.ba.tid = tid,
			.u.ba.sta = &sta->sta,
		};
		drv_event_callback(rx.local, rx.sdata, &event);
	}

	ieee80211_rx_handlers(&rx, &frames);
}


ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data,
	uint16_t fudge, const char *algorithm_name, const ldns_rdf *query_mac, int tsig_timers_only)
{
	ldns_rr *tsig_rr;
	ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name);
	ldns_rdf *fudge_rdf = NULL;
	ldns_rdf *orig_id_rdf = NULL;
	ldns_rdf *algorithm_rdf;
	ldns_rdf *error_rdf = NULL;
	ldns_rdf *mac_rdf = NULL;
	ldns_rdf *other_data_rdf = NULL;

	ldns_status status = LDNS_STATUS_OK;

	uint8_t *pkt_wire = NULL;
	size_t pkt_wire_len;

	struct timeval tv_time_signed;
	uint8_t *time_signed = NULL;
	ldns_rdf *time_signed_rdf = NULL;

	algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name);
	if(!key_name_rdf || !algorithm_rdf) {
		status = LDNS_STATUS_MEM_ERR;
		goto clean;
	}

	/* eww don't have create tsigtime rdf yet :( */
	/* bleh :p */
	if (gettimeofday(&tv_time_signed, NULL) == 0) {
		time_signed = LDNS_XMALLOC(uint8_t, 6);
		if(!time_signed) {
			status = LDNS_STATUS_MEM_ERR;
			goto clean;
		}
		ldns_write_uint64_as_uint48(time_signed,
				(uint64_t)tv_time_signed.tv_sec);
	} else {
		status = LDNS_STATUS_INTERNAL_ERR;
		goto clean;
	}

	time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed);
	if(!time_signed_rdf) {
		LDNS_FREE(time_signed);
		status = LDNS_STATUS_MEM_ERR;
		goto clean;
	}

	fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge);

	orig_id_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_pkt_id(pkt));

	error_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 0);

	other_data_rdf = ldns_native2rdf_int16_data(0, NULL);

	if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
		status = LDNS_STATUS_MEM_ERR;
		goto clean;
	}

	if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) {
		status = LDNS_STATUS_ERR;
		goto clean;
	}

	status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len,
			key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
			time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only);

	if (!mac_rdf) {
		goto clean;
	}

	LDNS_FREE(pkt_wire);

	/* Create the TSIG RR */
	tsig_rr = ldns_rr_new();
	if(!tsig_rr) {
		status = LDNS_STATUS_MEM_ERR;
		goto clean;
	}
	ldns_rr_set_owner(tsig_rr, key_name_rdf);
	ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY);
	ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG);
	ldns_rr_set_ttl(tsig_rr, 0);

	ldns_rr_push_rdf(tsig_rr, algorithm_rdf);
	ldns_rr_push_rdf(tsig_rr, time_signed_rdf);
	ldns_rr_push_rdf(tsig_rr, fudge_rdf);
	ldns_rr_push_rdf(tsig_rr, mac_rdf);
	ldns_rr_push_rdf(tsig_rr, orig_id_rdf);
	ldns_rr_push_rdf(tsig_rr, error_rdf);
	ldns_rr_push_rdf(tsig_rr, other_data_rdf);

	ldns_pkt_set_tsig(pkt, tsig_rr);

	return status;

  clean:
	LDNS_FREE(pkt_wire);
	ldns_rdf_free(key_name_rdf);
	ldns_rdf_free(algorithm_rdf);
	ldns_rdf_free(time_signed_rdf);
	ldns_rdf_free(fudge_rdf);
	ldns_rdf_free(orig_id_rdf);
	ldns_rdf_free(error_rdf);
	ldns_rdf_free(other_data_rdf);
	return status;
}


ldns_tsig_keyname(const ldns_tsig_credentials *tc)
{
	return tc->keyname;
}


ldns_tsig_keyname_clone(const ldns_tsig_credentials *tc)
{
	return strdup(tc->keyname);
}


ldns_digest_function(char *name)
{
	/* these are the mandatory algorithms from RFC4635 */
	/* The optional algorithms are not yet implemented */
	if (strcasecmp(name, "hmac-sha512.") == 0) {
#ifdef HAVE_EVP_SHA512
		return EVP_sha512();
#else
		return NULL;
#endif
	} else if (strcasecmp(name, "hmac-shac384.") == 0) {
#ifdef HAVE_EVP_SHA384
		return EVP_sha384();
#else
		return NULL;
#endif
	} else if (strcasecmp(name, "hmac-sha256.") == 0) {
#ifdef HAVE_EVP_SHA256
		return EVP_sha256();
#else
		return NULL;
#endif
	} else if (strcasecmp(name, "hmac-sha1.") == 0) {
		return EVP_sha1();
	} else if (strcasecmp(name, "hmac-md5.sig-alg.reg.int.") == 0) {
		return EVP_md5();
	} else {
		return NULL;
	}
}


int close_fd_get_file(unsigned int fd, struct file **res)
{
	struct files_struct *files = current->files;
	int ret;

	spin_lock(&files->file_lock);
	ret = __close_fd_get_file(fd, res);
	spin_unlock(&files->file_lock);

	return ret;
}


_ber_get_len(BerElement *ber, ber_len_t *lenp)
{
    OLBerElement *lber = (OLBerElement *)ber;

    if (NULL == lenp) {
        return LBER_DEFAULT;
    }
    *lenp = 0;
    if (NULL == lber) {
        return LBER_DEFAULT;
    }
    *lenp = lber->ber_len;
    return lber->ber_tag;
}


slapi_pblock_set_vattr_context(Slapi_PBlock *pb, void *vattr_ctx)
{
#ifdef PBLOCK_ANALYTICS
    pblock_analytics_record(pb, SLAPI_VATTR_CONTEXT);
#endif
    _pblock_assert_pb_intplugin(pb);
    pb->pb_intplugin->pb_vattr_context = vattr_ctx;
}


pblock_analytics_query(Slapi_PBlock *pb, int access_type)
{
    uint64_t uact = (uint64_t)access_type;
    /* For testing, allow querying of the stats we have taken. */
    return (uint64_t)PL_HashTableLookup(pb->analytics, (void *)uact);
}


slapi_pblock_get_pw_entry(Slapi_PBlock *pb)
{
#ifdef PBLOCK_ANALYTICS
    pblock_analytics_record(pb, SLAPI_PW_ENTRY);
#endif
    if (pb->pb_intop != NULL) {
        return pb->pb_intop->pb_pw_entry;
    }
    return NULL;
}


connection_read_ldap_data(Connection *conn, PRInt32 *err)
{
    int ret = 0;
    ret = PR_Recv(conn->c_prfd, conn->c_private->c_buffer, conn->c_private->c_buffer_size, 0, PR_INTERVAL_NO_WAIT);
    if (ret < 0) {
        *err = PR_GetError();
    } else if (CONNECTION_BUFFER_ADAPT == conn->c_private->use_buffer) {
        if ((ret == conn->c_private->c_buffer_size) && (conn->c_private->c_buffer_size < BUFSIZ)) {
            /* we read exactly what we requested - there could be more that we could have read */
            /* so increase the buffer size */
            conn->c_private->c_buffer_size *= 2;
            if (conn->c_private->c_buffer_size > BUFSIZ) {
                conn->c_private->c_buffer_size = BUFSIZ;
            }
            conn->c_private->c_buffer = slapi_ch_realloc(conn->c_private->c_buffer, conn->c_private->c_buffer_size);
        }
    }
    return ret;
}


conn_buffered_data_avail_nolock(Connection *conn, int *conn_closed)
{
    if ((conn->c_sd == SLAPD_INVALID_SOCKET) || (conn->c_flags & CONN_FLAG_CLOSING)) {
        /* connection is closed - ignore the buffer */
        *conn_closed = 1;
        return 0;
    } else {
        *conn_closed = 0;
        return conn->c_private->c_buffer_bytes - conn->c_private->c_buffer_offset;
    }
}


static inline int max_evtchn_port(struct kvm *kvm)
{
	if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
		return EVTCHN_2L_NR_CHANNELS;
	else
		return COMPAT_EVTCHN_2L_NR_CHANNELS;
}


static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
{
	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
	char instruction[3];
	unsigned long rip = kvm_rip_read(vcpu);

	static_call(kvm_x86_patch_hypercall)(vcpu, instruction);

	return emulator_write_emulated(ctxt, rip, instruction, 3,
		&ctxt->exception);
}


void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu)
{
	if (vcpu->arch.guest_state_protected)
		return;

	if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) {

		if (vcpu->arch.xcr0 != host_xcr0)
			xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0);

		if (vcpu->arch.xsaves_enabled &&
		    vcpu->arch.ia32_xss != host_xss)
			wrmsrl(MSR_IA32_XSS, vcpu->arch.ia32_xss);
	}

	if (static_cpu_has(X86_FEATURE_PKU) &&
	    (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) ||
	     (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU)) &&
	    vcpu->arch.pkru != vcpu->arch.host_pkru)
		write_pkru(vcpu->arch.pkru);
}


void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
{
	down_write(&kvm->arch.apicv_update_lock);
	__kvm_request_apicv_update(kvm, activate, bit);
	up_write(&kvm->arch.apicv_update_lock);
}


static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
{
	if (!list_empty_careful(&vcpu->async_pf.done))
		return true;

	if (kvm_apic_has_events(vcpu))
		return true;

	if (vcpu->arch.pv.pv_unhalted)
		return true;

	if (vcpu->arch.exception.pending)
		return true;

	if (kvm_test_request(KVM_REQ_NMI, vcpu) ||
	    (vcpu->arch.nmi_pending &&
	     static_call(kvm_x86_nmi_allowed)(vcpu, false)))
		return true;

	if (kvm_test_request(KVM_REQ_SMI, vcpu) ||
	    (vcpu->arch.smi_pending &&
	     static_call(kvm_x86_smi_allowed)(vcpu, false)))
		return true;

	if (kvm_arch_interrupt_allowed(vcpu) &&
	    (kvm_cpu_has_interrupt(vcpu) ||
	    kvm_guest_apic_has_interrupt(vcpu)))
		return true;

	if (kvm_hv_has_stimer_pending(vcpu))
		return true;

	if (is_guest_mode(vcpu) &&
	    kvm_x86_ops.nested_ops->hv_timer_pending &&
	    kvm_x86_ops.nested_ops->hv_timer_pending(vcpu))
		return true;

	return false;
}


static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val,
			      unsigned int bytes, struct x86_exception *exception,
			      bool system)
{
	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
	u32 access = PFERR_WRITE_MASK;

	if (!system && static_call(kvm_x86_get_cpl)(vcpu) == 3)
		access |= PFERR_USER_MASK;

	return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
					   access, exception);
}


int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
			    int emulation_type, void *insn, int insn_len)
{
	int r;
	struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt;
	bool writeback = true;
	bool write_fault_to_spt;

	if (unlikely(!static_call(kvm_x86_can_emulate_instruction)(vcpu, insn, insn_len)))
		return 1;

	vcpu->arch.l1tf_flush_l1d = true;

	/*
	 * Clear write_fault_to_shadow_pgtable here to ensure it is
	 * never reused.
	 */
	write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable;
	vcpu->arch.write_fault_to_shadow_pgtable = false;

	if (!(emulation_type & EMULTYPE_NO_DECODE)) {
		kvm_clear_exception_queue(vcpu);

		r = x86_decode_emulated_instruction(vcpu, emulation_type,
						    insn, insn_len);
		if (r != EMULATION_OK)  {
			if ((emulation_type & EMULTYPE_TRAP_UD) ||
			    (emulation_type & EMULTYPE_TRAP_UD_FORCED)) {
				kvm_queue_exception(vcpu, UD_VECTOR);
				return 1;
			}
			if (reexecute_instruction(vcpu, cr2_or_gpa,
						  write_fault_to_spt,
						  emulation_type))
				return 1;
			if (ctxt->have_exception) {
				/*
				 * #UD should result in just EMULATION_FAILED, and trap-like
				 * exception should not be encountered during decode.
				 */
				WARN_ON_ONCE(ctxt->exception.vector == UD_VECTOR ||
					     exception_type(ctxt->exception.vector) == EXCPT_TRAP);
				inject_emulated_exception(vcpu);
				return 1;
			}
			return handle_emulation_failure(vcpu, emulation_type);
		}
	}

	if ((emulation_type & EMULTYPE_VMWARE_GP) &&
	    !is_vmware_backdoor_opcode(ctxt)) {
		kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
		return 1;
	}

	/*
	 * EMULTYPE_SKIP without EMULTYPE_COMPLETE_USER_EXIT is intended for
	 * use *only* by vendor callbacks for kvm_skip_emulated_instruction().
	 * The caller is responsible for updating interruptibility state and
	 * injecting single-step #DBs.
	 */
	if (emulation_type & EMULTYPE_SKIP) {
		if (ctxt->mode != X86EMUL_MODE_PROT64)
			ctxt->eip = (u32)ctxt->_eip;
		else
			ctxt->eip = ctxt->_eip;

		if (emulation_type & EMULTYPE_COMPLETE_USER_EXIT) {
			r = 1;
			goto writeback;
		}

		kvm_rip_write(vcpu, ctxt->eip);
		if (ctxt->eflags & X86_EFLAGS_RF)
			kvm_set_rflags(vcpu, ctxt->eflags & ~X86_EFLAGS_RF);
		return 1;
	}

	if (retry_instruction(ctxt, cr2_or_gpa, emulation_type))
		return 1;

	/* this is needed for vmware backdoor interface to work since it
	   changes registers values  during IO operation */
	if (vcpu->arch.emulate_regs_need_sync_from_vcpu) {
		vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
		emulator_invalidate_register_cache(ctxt);
	}

restart:
	if (emulation_type & EMULTYPE_PF) {
		/* Save the faulting GPA (cr2) in the address field */
		ctxt->exception.address = cr2_or_gpa;

		/* With shadow page tables, cr2 contains a GVA or nGPA. */
		if (vcpu->arch.mmu->direct_map) {
			ctxt->gpa_available = true;
			ctxt->gpa_val = cr2_or_gpa;
		}
	} else {
		/* Sanitize the address out of an abundance of paranoia. */
		ctxt->exception.address = 0;
	}

	r = x86_emulate_insn(ctxt);

	if (r == EMULATION_INTERCEPTED)
		return 1;

	if (r == EMULATION_FAILED) {
		if (reexecute_instruction(vcpu, cr2_or_gpa, write_fault_to_spt,
					emulation_type))
			return 1;

		return handle_emulation_failure(vcpu, emulation_type);
	}

	if (ctxt->have_exception) {
		r = 1;
		if (inject_emulated_exception(vcpu))
			return r;
	} else if (vcpu->arch.pio.count) {
		if (!vcpu->arch.pio.in) {
			/* FIXME: return into emulator if single-stepping.  */
			vcpu->arch.pio.count = 0;
		} else {
			writeback = false;
			vcpu->arch.complete_userspace_io = complete_emulated_pio;
		}
		r = 0;
	} else if (vcpu->mmio_needed) {
		++vcpu->stat.mmio_exits;

		if (!vcpu->mmio_is_write)
			writeback = false;
		r = 0;
		vcpu->arch.complete_userspace_io = complete_emulated_mmio;
	} else if (vcpu->arch.complete_userspace_io) {
		writeback = false;
		r = 0;
	} else if (r == EMULATION_RESTART)
		goto restart;
	else
		r = 1;

writeback:
	if (writeback) {
		unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
		toggle_interruptibility(vcpu, ctxt->interruptibility);
		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
		if (!ctxt->have_exception ||
		    exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
			kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
			if (ctxt->is_branch)
				kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
			kvm_rip_write(vcpu, ctxt->eip);
			if (r && (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
				r = kvm_vcpu_do_singlestep(vcpu);
			if (kvm_x86_ops.update_emulated_instruction)
				static_call(kvm_x86_update_emulated_instruction)(vcpu);
			__kvm_set_rflags(vcpu, ctxt->eflags);
		}

		/*
		 * For STI, interrupts are shadowed; so KVM_REQ_EVENT will
		 * do nothing, and it will be requested again as soon as
		 * the shadow expires.  But we still need to check here,
		 * because POPF has no interrupt shadow.
		 */
		if (unlikely((ctxt->eflags & ~rflags) & X86_EFLAGS_IF))
			kvm_make_request(KVM_REQ_EVENT, vcpu);
	} else
		vcpu->arch.emulate_regs_need_sync_to_vcpu = true;

	return r;
}


static void kvm_setup_pvclock_page(struct kvm_vcpu *v,
				   struct gfn_to_hva_cache *cache,
				   unsigned int offset)
{
	struct kvm_vcpu_arch *vcpu = &v->arch;
	struct pvclock_vcpu_time_info guest_hv_clock;

	if (unlikely(kvm_read_guest_offset_cached(v->kvm, cache,
		&guest_hv_clock, offset, sizeof(guest_hv_clock))))
		return;

	/* This VCPU is paused, but it's legal for a guest to read another
	 * VCPU's kvmclock, so we really have to follow the specification where
	 * it says that version is odd if data is being modified, and even after
	 * it is consistent.
	 *
	 * Version field updates must be kept separate.  This is because
	 * kvm_write_guest_cached might use a "rep movs" instruction, and
	 * writes within a string instruction are weakly ordered.  So there
	 * are three writes overall.
	 *
	 * As a small optimization, only write the version field in the first
	 * and third write.  The vcpu->pv_time cache is still valid, because the
	 * version field is the first in the struct.
	 */
	BUILD_BUG_ON(offsetof(struct pvclock_vcpu_time_info, version) != 0);

	if (guest_hv_clock.version & 1)
		++guest_hv_clock.version;  /* first time write, random junk */

	vcpu->hv_clock.version = guest_hv_clock.version + 1;
	kvm_write_guest_offset_cached(v->kvm, cache,
				      &vcpu->hv_clock, offset,
				      sizeof(vcpu->hv_clock.version));

	smp_wmb();

	/* retain PVCLOCK_GUEST_STOPPED if set in guest copy */
	vcpu->hv_clock.flags |= (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED);

	if (vcpu->pvclock_set_guest_stopped_request) {
		vcpu->hv_clock.flags |= PVCLOCK_GUEST_STOPPED;
		vcpu->pvclock_set_guest_stopped_request = false;
	}

	trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock);

	kvm_write_guest_offset_cached(v->kvm, cache,
				      &vcpu->hv_clock, offset,
				      sizeof(vcpu->hv_clock));

	smp_wmb();

	vcpu->hv_clock.version++;
	kvm_write_guest_offset_cached(v->kvm, cache,
				     &vcpu->hv_clock, offset,
				     sizeof(vcpu->hv_clock.version));
}


static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
{
	++vcpu->stat.tlb_flush;

	if (!tdp_enabled) {
		/*
		 * A TLB flush on behalf of the guest is equivalent to
		 * INVPCID(all), toggling CR4.PGE, etc., which requires
		 * a forced sync of the shadow page tables.  Ensure all the
		 * roots are synced and the guest TLB in hardware is clean.
		 */
		kvm_mmu_sync_roots(vcpu);
		kvm_mmu_sync_prev_roots(vcpu);
	}

	static_call(kvm_x86_tlb_flush_guest)(vcpu);
}


static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
{
	int error = 0;
	struct file *file = priv;
	struct eventpoll *ep = file->private_data;
	struct eventpoll *ep_tovisit;
	struct rb_node *rbp;
	struct epitem *epi;

	mutex_lock_nested(&ep->mtx, call_nests + 1);
	ep->visited = 1;
	list_add(&ep->visited_list_link, &visited_list);
	for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) {
		epi = rb_entry(rbp, struct epitem, rbn);
		if (unlikely(is_file_epoll(epi->ffd.file))) {
			ep_tovisit = epi->ffd.file->private_data;
			if (ep_tovisit->visited)
				continue;
			error = ep_call_nested(&poll_loop_ncalls,
					ep_loop_check_proc, epi->ffd.file,
					ep_tovisit, current);
			if (error != 0)
				break;
		} else {
			/*
			 * If we've reached a file that is not associated with
			 * an ep, then we need to check if the newly added
			 * links are going to add too many wakeup paths. We do
			 * this by adding it to the tfile_check_list, if it's
			 * not already there, and calling reverse_path_check()
			 * during ep_insert().
			 */
			if (list_empty(&epi->ffd.file->f_tfile_llink)) {
				if (get_file_rcu(epi->ffd.file))
					list_add(&epi->ffd.file->f_tfile_llink,
						 &tfile_check_list);
			}
		}
	}
	mutex_unlock(&ep->mtx);

	return error;
}


static int unix_stream_read_generic(struct unix_stream_read_state *state,
				    bool freezable)
{
	struct scm_cookie scm;
	struct socket *sock = state->socket;
	struct sock *sk = sock->sk;
	struct unix_sock *u = unix_sk(sk);
	int copied = 0;
	int flags = state->flags;
	int noblock = flags & MSG_DONTWAIT;
	bool check_creds = false;
	int target;
	int err = 0;
	long timeo;
	int skip;
	size_t size = state->size;
	unsigned int last_len;

	if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
		err = -EINVAL;
		goto out;
	}

	if (unlikely(flags & MSG_OOB)) {
		err = -EOPNOTSUPP;
		goto out;
	}

	target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
	timeo = sock_rcvtimeo(sk, noblock);

	memset(&scm, 0, sizeof(scm));

	/* Lock the socket to prevent queue disordering
	 * while sleeps in memcpy_tomsg
	 */
	mutex_lock(&u->iolock);

	skip = max(sk_peek_offset(sk, flags), 0);

	do {
		int chunk;
		bool drop_skb;
		struct sk_buff *skb, *last;

redo:
		unix_state_lock(sk);
		if (sock_flag(sk, SOCK_DEAD)) {
			err = -ECONNRESET;
			goto unlock;
		}
		last = skb = skb_peek(&sk->sk_receive_queue);
		last_len = last ? last->len : 0;
again:
		if (skb == NULL) {
			if (copied >= target)
				goto unlock;

			/*
			 *	POSIX 1003.1g mandates this order.
			 */

			err = sock_error(sk);
			if (err)
				goto unlock;
			if (sk->sk_shutdown & RCV_SHUTDOWN)
				goto unlock;

			unix_state_unlock(sk);
			if (!timeo) {
				err = -EAGAIN;
				break;
			}

			mutex_unlock(&u->iolock);

			timeo = unix_stream_data_wait(sk, timeo, last,
						      last_len, freezable);

			if (signal_pending(current)) {
				err = sock_intr_errno(timeo);
				scm_destroy(&scm);
				goto out;
			}

			mutex_lock(&u->iolock);
			goto redo;
unlock:
			unix_state_unlock(sk);
			break;
		}

		while (skip >= unix_skb_len(skb)) {
			skip -= unix_skb_len(skb);
			last = skb;
			last_len = skb->len;
			skb = skb_peek_next(skb, &sk->sk_receive_queue);
			if (!skb)
				goto again;
		}

		unix_state_unlock(sk);

		if (check_creds) {
			/* Never glue messages from different writers */
			if (!unix_skb_scm_eq(skb, &scm))
				break;
		} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
			/* Copy credentials */
			scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
			unix_set_secdata(&scm, skb);
			check_creds = true;
		}

		/* Copy address just once */
		if (state->msg && state->msg->msg_name) {
			DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
					 state->msg->msg_name);
			unix_copy_addr(state->msg, skb->sk);
			sunaddr = NULL;
		}

		chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
		skb_get(skb);
		chunk = state->recv_actor(skb, skip, chunk, state);
		drop_skb = !unix_skb_len(skb);
		/* skb is only safe to use if !drop_skb */
		consume_skb(skb);
		if (chunk < 0) {
			if (copied == 0)
				copied = -EFAULT;
			break;
		}
		copied += chunk;
		size -= chunk;

		if (drop_skb) {
			/* the skb was touched by a concurrent reader;
			 * we should not expect anything from this skb
			 * anymore and assume it invalid - we can be
			 * sure it was dropped from the socket queue
			 *
			 * let's report a short read
			 */
			err = 0;
			break;
		}

		/* Mark read part of skb as used */
		if (!(flags & MSG_PEEK)) {
			UNIXCB(skb).consumed += chunk;

			sk_peek_offset_bwd(sk, chunk);

			if (UNIXCB(skb).fp) {
				scm_stat_del(sk, skb);
				unix_detach_fds(&scm, skb);
			}

			if (unix_skb_len(skb))
				break;

			skb_unlink(skb, &sk->sk_receive_queue);
			consume_skb(skb);

			if (scm.fp)
				break;
		} else {
			/* It is questionable, see note in unix_dgram_recvmsg.
			 */
			if (UNIXCB(skb).fp)
				unix_peek_fds(&scm, skb);

			sk_peek_offset_fwd(sk, chunk);

			if (UNIXCB(skb).fp)
				break;

			skip = 0;
			last = skb;
			last_len = skb->len;
			unix_state_lock(sk);
			skb = skb_peek_next(skb, &sk->sk_receive_queue);
			if (skb)
				goto again;
			unix_state_unlock(sk);
			break;
		}
	} while (size);

	mutex_unlock(&u->iolock);
	if (state->msg)
		scm_recv(sock, state->msg, &scm, flags);
	else
		scm_destroy(&scm);
out:
	return copied ? : err;
}


static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
			       size_t len)
{
	struct sock *sk = sock->sk;
	struct sock *other = NULL;
	int err, size;
	struct sk_buff *skb;
	int sent = 0;
	struct scm_cookie scm;
	bool fds_sent = false;
	int data_len;

	wait_for_unix_gc();
	err = scm_send(sock, msg, &scm, false);
	if (err < 0)
		return err;

	err = -EOPNOTSUPP;
	if (msg->msg_flags&MSG_OOB)
		goto out_err;

	if (msg->msg_namelen) {
		err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
		goto out_err;
	} else {
		err = -ENOTCONN;
		other = unix_peer(sk);
		if (!other)
			goto out_err;
	}

	if (sk->sk_shutdown & SEND_SHUTDOWN)
		goto pipe_err;

	while (sent < len) {
		size = len - sent;

		/* Keep two messages in the pipe so it schedules better */
		size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);

		/* allow fallback to order-0 allocations */
		size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);

		data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));

		data_len = min_t(size_t, size, PAGE_ALIGN(data_len));

		skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
					   msg->msg_flags & MSG_DONTWAIT, &err,
					   get_order(UNIX_SKB_FRAGS_SZ));
		if (!skb)
			goto out_err;

		/* Only send the fds in the first buffer */
		err = unix_scm_to_skb(&scm, skb, !fds_sent);
		if (err < 0) {
			kfree_skb(skb);
			goto out_err;
		}
		fds_sent = true;

		skb_put(skb, size - data_len);
		skb->data_len = data_len;
		skb->len = size;
		err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
		if (err) {
			kfree_skb(skb);
			goto out_err;
		}

		unix_state_lock(other);

		if (sock_flag(other, SOCK_DEAD) ||
		    (other->sk_shutdown & RCV_SHUTDOWN))
			goto pipe_err_free;

		maybe_add_creds(skb, sock, other);
		scm_stat_add(other, skb);
		skb_queue_tail(&other->sk_receive_queue, skb);
		unix_state_unlock(other);
		other->sk_data_ready(other);
		sent += size;
	}

	scm_destroy(&scm);

	return sent;

pipe_err_free:
	unix_state_unlock(other);
	kfree_skb(skb);
pipe_err:
	if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
		send_sig(SIGPIPE, current, 0);
	err = -EPIPE;
out_err:
	scm_destroy(&scm);
	return sent ? : err;
}


static int unix_listen(struct socket *sock, int backlog)
{
	int err;
	struct sock *sk = sock->sk;
	struct unix_sock *u = unix_sk(sk);

	err = -EOPNOTSUPP;
	if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
		goto out;	/* Only stream/seqpacket sockets accept */
	err = -EINVAL;
	if (!u->addr)
		goto out;	/* No listens on an unbound socket */
	unix_state_lock(sk);
	if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
		goto out_unlock;
	if (backlog > sk->sk_max_ack_backlog)
		wake_up_interruptible_all(&u->peer_wait);
	sk->sk_max_ack_backlog	= backlog;
	sk->sk_state		= TCP_LISTEN;
	/* set credentials so connect can copy them */
	init_peercred(sk);
	err = 0;

out_unlock:
	unix_state_unlock(sk);
out:
	return err;
}


static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
				    int offset, size_t size, int flags)
{
	int err;
	bool send_sigpipe = false;
	bool init_scm = true;
	struct scm_cookie scm;
	struct sock *other, *sk = socket->sk;
	struct sk_buff *skb, *newskb = NULL, *tail = NULL;

	if (flags & MSG_OOB)
		return -EOPNOTSUPP;

	other = unix_peer(sk);
	if (!other || sk->sk_state != TCP_ESTABLISHED)
		return -ENOTCONN;

	if (false) {
alloc_skb:
		unix_state_unlock(other);
		mutex_unlock(&unix_sk(other)->iolock);
		newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
					      &err, 0);
		if (!newskb)
			goto err;
	}

	/* we must acquire iolock as we modify already present
	 * skbs in the sk_receive_queue and mess with skb->len
	 */
	err = mutex_lock_interruptible(&unix_sk(other)->iolock);
	if (err) {
		err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
		goto err;
	}

	if (sk->sk_shutdown & SEND_SHUTDOWN) {
		err = -EPIPE;
		send_sigpipe = true;
		goto err_unlock;
	}

	unix_state_lock(other);

	if (sock_flag(other, SOCK_DEAD) ||
	    other->sk_shutdown & RCV_SHUTDOWN) {
		err = -EPIPE;
		send_sigpipe = true;
		goto err_state_unlock;
	}

	if (init_scm) {
		err = maybe_init_creds(&scm, socket, other);
		if (err)
			goto err_state_unlock;
		init_scm = false;
	}

	skb = skb_peek_tail(&other->sk_receive_queue);
	if (tail && tail == skb) {
		skb = newskb;
	} else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
		if (newskb) {
			skb = newskb;
		} else {
			tail = skb;
			goto alloc_skb;
		}
	} else if (newskb) {
		/* this is fast path, we don't necessarily need to
		 * call to kfree_skb even though with newskb == NULL
		 * this - does no harm
		 */
		consume_skb(newskb);
		newskb = NULL;
	}

	if (skb_append_pagefrags(skb, page, offset, size)) {
		tail = skb;
		goto alloc_skb;
	}

	skb->len += size;
	skb->data_len += size;
	skb->truesize += size;
	refcount_add(size, &sk->sk_wmem_alloc);

	if (newskb) {
		err = unix_scm_to_skb(&scm, skb, false);
		if (err)
			goto err_state_unlock;
		spin_lock(&other->sk_receive_queue.lock);
		__skb_queue_tail(&other->sk_receive_queue, newskb);
		spin_unlock(&other->sk_receive_queue.lock);
	}

	unix_state_unlock(other);
	mutex_unlock(&unix_sk(other)->iolock);

	other->sk_data_ready(other);
	scm_destroy(&scm);
	return size;

err_state_unlock:
	unix_state_unlock(other);
err_unlock:
	mutex_unlock(&unix_sk(other)->iolock);
err:
	kfree_skb(newskb);
	if (send_sigpipe && !(flags & MSG_NOSIGNAL))
		send_sig(SIGPIPE, current, 0);
	if (!init_scm)
		scm_destroy(&scm);
	return err;
}


crypt_keyslot_info crypt_keyslot_status(struct crypt_device *cd, int keyslot)
{
	if (_onlyLUKS(cd, CRYPT_CD_QUIET | CRYPT_CD_UNRESTRICTED) < 0)
		return CRYPT_SLOT_INVALID;

	if (isLUKS1(cd->type))
		return LUKS_keyslot_info(&cd->u.luks1.hdr, keyslot);
	else if(isLUKS2(cd->type))
		return LUKS2_keyslot_info(&cd->u.luks2.hdr, keyslot);

	return CRYPT_SLOT_INVALID;
}


int crypt_memory_lock(struct crypt_device *cd, int lock)
{
	return lock ? crypt_memlock_inc(cd) : crypt_memlock_dec(cd);
}


static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks)
{
	int r;
	struct volume_key *vk = vks;

	while (vk) {
		r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
		if (r < 0)
			return r;
		vk = crypt_volume_key_next(vk);
	}

	return 0;
}


int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
				 struct luks2_keyslot_params *params)
{
	const struct crypt_pbkdf_type *pbkdf = crypt_get_pbkdf_type(cd);
	const char *cipher_spec;
	size_t key_size;
	int r;

	if (!hdr || !pbkdf || !params)
		return -EINVAL;

	/*
	 * set keyslot area encryption parameters
	 */
	params->area_type = LUKS2_KEYSLOT_AREA_RAW;
	cipher_spec = crypt_keyslot_get_encryption(cd, CRYPT_ANY_SLOT, &key_size);
	if (!cipher_spec || !key_size)
		return -EINVAL;

	params->area.raw.key_size = key_size;
	r = snprintf(params->area.raw.encryption, sizeof(params->area.raw.encryption), "%s", cipher_spec);
	if (r < 0 || (size_t)r >= sizeof(params->area.raw.encryption))
		return -EINVAL;

	/*
	 * set keyslot AF parameters
	 */
	params->af_type = LUKS2_KEYSLOT_AF_LUKS1;
	/* currently we use hash for AF from pbkdf settings */
	r = snprintf(params->af.luks1.hash, sizeof(params->af.luks1.hash), "%s", pbkdf->hash ?: DEFAULT_LUKS1_HASH);
	if (r < 0 || (size_t)r >= sizeof(params->af.luks1.hash))
		return -EINVAL;
	params->af.luks1.stripes = 4000;

	return 0;
}


static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t dev_size, uint64_t data_shift, bool move_first_segment, crypt_reencrypt_direction_info di)
{
	int r;
	uint64_t first_segment_offset, first_segment_length,
		 second_segment_offset, second_segment_length,
		 data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT,
		 data_size = dev_size - data_shift;
	json_object *jobj_segment_first = NULL, *jobj_segment_second = NULL, *jobj_segments;

	if (dev_size < data_shift)
		return -EINVAL;

	if (data_shift && (di == CRYPT_REENCRYPT_FORWARD))
		return -ENOTSUP;

	if (move_first_segment) {
		/*
		 * future data_device layout:
		 * [future LUKS2 header (data shift size)][second data segment][gap (data shift size)][first data segment (data shift size)]
		 */
		first_segment_offset = dev_size;
		if (data_size < data_shift) {
			first_segment_length = data_size;
			second_segment_length = second_segment_offset = 0;
		} else {
			first_segment_length = data_shift;
			second_segment_offset = data_shift;
			second_segment_length = data_size - data_shift;
		}
	} else if (data_shift) {
		first_segment_offset = data_offset;
		first_segment_length = dev_size;
	} else {
		/* future data_device layout with detached header: [first data segment] */
		first_segment_offset = data_offset;
		first_segment_length = 0; /* dynamic */
	}

	jobj_segments = json_object_new_object();
	if (!jobj_segments)
		return -ENOMEM;

	r = -EINVAL;
	if (move_first_segment) {
		jobj_segment_first =  json_segment_create_linear(first_segment_offset, &first_segment_length, 0);
		if (second_segment_length &&
		    !(jobj_segment_second = json_segment_create_linear(second_segment_offset, &second_segment_length, 0))) {
			log_dbg(cd, "Failed generate 2nd segment.");
			return r;
		}
	} else
		jobj_segment_first =  json_segment_create_linear(first_segment_offset, first_segment_length ? &first_segment_length : NULL, 0);

	if (!jobj_segment_first) {
		log_dbg(cd, "Failed generate 1st segment.");
		return r;
	}

	json_object_object_add(jobj_segments, "0", jobj_segment_first);
	if (jobj_segment_second)
		json_object_object_add(jobj_segments, "1", jobj_segment_second);

	r = LUKS2_digest_segment_assign(cd, hdr, CRYPT_ANY_SEGMENT, CRYPT_ANY_DIGEST, 0, 0);

	return r ?: LUKS2_segments_set(cd, hdr, jobj_segments, 0);
}


const char *crypt_get_uuid(struct crypt_device *cd)
{
	if (!cd)
		return NULL;

	if (isLUKS1(cd->type))
		return cd->u.luks1.hdr.uuid;

	if (isLUKS2(cd->type))
		return cd->u.luks2.hdr.uuid;

	if (isVERITY(cd->type))
		return cd->u.verity.uuid;

	if (isBITLK(cd->type))
		return cd->u.bitlk.params.guid;

	return NULL;
}


crypt_keyslot_priority LUKS2_keyslot_priority_get(struct crypt_device *cd __attribute__((unused)),
	  struct luks2_hdr *hdr, int keyslot)
{
	json_object *jobj_keyslot, *jobj_priority;

	jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
	if (!jobj_keyslot)
		return CRYPT_SLOT_PRIORITY_INVALID;

	if (!json_object_object_get_ex(jobj_keyslot, "priority", &jobj_priority))
		return CRYPT_SLOT_PRIORITY_NORMAL;

	return json_object_get_int(jobj_priority);
}


static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
			    int require_header, int repair)
{
	char *cipher_spec;
	struct luks_phdr hdr = {};
	int r, version;

	r = init_crypto(cd);
	if (r < 0)
		return r;

	/* This will return 0 if primary LUKS2 header is damaged */
	version = LUKS2_hdr_version_unlocked(cd, NULL);

	if ((isLUKS1(requested_type) && version == 2) ||
	    (isLUKS2(requested_type) && version == 1))
		return -EINVAL;

	if (requested_type)
		version = 0;

	if (isLUKS1(requested_type) || version == 1) {
		if (isLUKS2(cd->type)) {
			log_dbg(cd, "Context is already initialized to type %s", cd->type);
			return -EINVAL;
		}

		if (verify_pbkdf_params(cd, &cd->pbkdf)) {
			r = init_pbkdf_type(cd, NULL, CRYPT_LUKS1);
			if (r)
				return r;
		}

		r = LUKS_read_phdr(&hdr, require_header, repair, cd);
		if (r)
			goto out;

		if (!cd->type && !(cd->type = strdup(CRYPT_LUKS1))) {
			r = -ENOMEM;
			goto out;
		}

		/* Set hash to the same as in the loaded header */
		if (!cd->pbkdf.hash || strcmp(cd->pbkdf.hash, hdr.hashSpec)) {
			free(CONST_CAST(void*)cd->pbkdf.hash);
			cd->pbkdf.hash = strdup(hdr.hashSpec);
			if (!cd->pbkdf.hash) {
				r = -ENOMEM;
				goto out;
			}
		}

		if (asprintf(&cipher_spec, "%s-%s", hdr.cipherName, hdr.cipherMode) < 0) {
			r = -ENOMEM;
			goto out;
		}

		free(cd->u.luks1.cipher_spec);
		cd->u.luks1.cipher_spec = cipher_spec;

		memcpy(&cd->u.luks1.hdr, &hdr, sizeof(hdr));
	} else if (isLUKS2(requested_type) || version == 2 || version == 0) {
		if (isLUKS1(cd->type)) {
			log_dbg(cd, "Context is already initialized to type %s", cd->type);
			return -EINVAL;
		}

		/*
		 * Current LUKS2 repair just overrides blkid probes
		 * and perform auto-recovery if possible. This is safe
		 * unless future LUKS2 repair code do something more
		 * sophisticated. In such case we would need to check
		 * for LUKS2 requirements and decide if it's safe to
		 * perform repair.
		 */
		r =  _crypt_load_luks2(cd, cd->type != NULL, repair);
		if (!r)
			device_set_block_size(crypt_data_device(cd), LUKS2_get_sector_size(&cd->u.luks2.hdr));
	} else {
		if (version > 2)
			log_err(cd, _("Unsupported LUKS version %d."), version);
		r = -EINVAL;
	}
out:
	crypt_safe_memzero(&hdr, sizeof(hdr));

	return r;
}


crypt_token_info crypt_token_status(struct crypt_device *cd, int token, const char **type)
{
	if (_onlyLUKS2(cd, CRYPT_CD_QUIET | CRYPT_CD_UNRESTRICTED, 0))
		return CRYPT_TOKEN_INVALID;

	return LUKS2_token_status(cd, &cd->u.luks2.hdr, token, type);
}


int crypt_init_data_device(struct crypt_device **cd, const char *device, const char *data_device)
{
	int r;

	if (!cd)
		return -EINVAL;

	r = crypt_init(cd, device);
	if (r || !data_device || !strcmp(device, data_device))
		return r;

	log_dbg(NULL, "Setting ciphertext data device to %s.", data_device);
	r = _crypt_set_data_device(*cd, data_device);
	if (r) {
		crypt_free(*cd);
		*cd = NULL;
	}

	return r;
}


static int _crypt_load_luks2(struct crypt_device *cd, int reload, int repair)
{
	int r;
	char *type = NULL;
	struct luks2_hdr hdr2 = {};

	log_dbg(cd, "%soading LUKS2 header (repair %sabled).", reload ? "Rel" : "L", repair ? "en" : "dis");

	r = LUKS2_hdr_read(cd, &hdr2, repair);
	if (r)
		return r;

	if (!reload && !(type = strdup(CRYPT_LUKS2))) {
		r = -ENOMEM;
		goto out;
	}

	if (verify_pbkdf_params(cd, &cd->pbkdf)) {
		r = init_pbkdf_type(cd, NULL, CRYPT_LUKS2);
		if (r)
			goto out;
	}

	if (reload) {
		LUKS2_hdr_free(cd, &cd->u.luks2.hdr);
		free(cd->u.luks2.keyslot_cipher);
	} else
		cd->type = type;

	r = 0;
	memcpy(&cd->u.luks2.hdr, &hdr2, sizeof(hdr2));
	cd->u.luks2.keyslot_cipher = NULL;
	cd->u.luks2.rh = NULL;

out:
	if (r) {
		free(type);
		LUKS2_hdr_free(cd, &hdr2);
	}
	return r;
}


static int reenc_keyslot_store_data(struct crypt_device *cd,
	json_object *jobj_keyslot,
	const void *buffer, size_t buffer_len)
{
	int devfd, r;
	json_object *jobj_area, *jobj_offset, *jobj_length;
	uint64_t area_offset, area_length;
	struct device *device = crypt_metadata_device(cd);

	if (!json_object_object_get_ex(jobj_keyslot, "area", &jobj_area) ||
	    !json_object_object_get_ex(jobj_area, "offset", &jobj_offset) ||
	    !json_object_object_get_ex(jobj_area, "size", &jobj_length))
		return -EINVAL;

	area_offset = crypt_jobj_get_uint64(jobj_offset);
	area_length = crypt_jobj_get_uint64(jobj_length);

	if (!area_offset || !area_length || ((uint64_t)buffer_len > area_length))
		return -EINVAL;

	devfd = device_open_locked(cd, device, O_RDWR);
	if (devfd >= 0) {
		if (write_lseek_blockwise(devfd, device_block_size(cd, device),
					  device_alignment(device), CONST_CAST(void *)buffer,
					  buffer_len, area_offset) < 0)
			r = -EIO;
		else
			r = 0;
	} else
		r = -EINVAL;

	if (r)
		log_err(cd, _("IO error while encrypting keyslot."));

	return r;
}


static int _open_and_activate_luks2(struct crypt_device *cd,
	int keyslot,
	const char *name,
	const char *passphrase,
	size_t passphrase_size,
	uint32_t flags)
{
	crypt_reencrypt_info ri;
	int r, rv;
	struct luks2_hdr *hdr = &cd->u.luks2.hdr;
	struct volume_key *vks = NULL;

	ri = LUKS2_reencrypt_status(hdr);
	if (ri == CRYPT_REENCRYPT_INVALID)
		return -EINVAL;

	if (ri > CRYPT_REENCRYPT_NONE) {
		if (name)
			r = _open_and_activate_reencrypt_device(cd, hdr, keyslot, name, passphrase,
					passphrase_size, flags);
		else {
			r = _open_all_keys(cd, hdr, keyslot, passphrase,
					   passphrase_size, flags, &vks);
			if (r < 0)
				return r;

			rv = LUKS2_reencrypt_digest_verify(cd, hdr, vks);
			crypt_free_volume_key(vks);
			if (rv < 0)
				return rv;
		}
	} else
		r = _open_and_activate(cd, keyslot, name, passphrase,
				passphrase_size, flags);

	return r;
}


int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr)
{
	return reencrypt_digest(hdr, 0);
}


static int reencrypt_make_segments(struct crypt_device *cd,
	struct luks2_hdr *hdr,
	struct luks2_reencrypt *rh,
	uint64_t device_size)
{
	int r;
	uint64_t data_offset = reencrypt_get_data_offset_new(hdr);

	log_dbg(cd, "Calculating segments.");

	r = reencrypt_make_hot_segments(cd, hdr, rh, device_size, data_offset);
	if (!r) {
		r = reencrypt_make_post_segments(cd, hdr, rh, data_offset);
		if (r)
			json_object_put(rh->jobj_segs_hot);
	}

	if (r)
		log_dbg(cd, "Failed to make reencryption segments.");

	return r;
}


const char *crypt_get_default_type(void)
{
	return DEFAULT_LUKS_FORMAT;
}


int crypt_activate_by_volume_key(struct crypt_device *cd,
	const char *name,
	const char *volume_key,
	size_t volume_key_size,
	uint32_t flags)
{
	bool use_keyring;
	struct volume_key *vk = NULL;
	int r;

	if (!cd ||
	    ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd)))
		return -EINVAL;

	log_dbg(cd, "%s volume %s by volume key.", name ? "Activating" : "Checking",
		name ?: "");

	r = _activate_check_status(cd, name, flags & CRYPT_ACTIVATE_REFRESH);
	if (r < 0)
		return r;

	r = _check_header_data_overlap(cd, name);
	if (r < 0)
		return r;

	/* use key directly, no hash */
	if (isPLAIN(cd->type)) {
		if (!name)
			return -EINVAL;

		if (!volume_key || !volume_key_size || volume_key_size != cd->u.plain.key_size) {
			log_err(cd, _("Incorrect volume key specified for plain device."));
			return -EINVAL;
		}

		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
		if (!vk)
			return -ENOMEM;

		r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags);
	} else if (isLUKS1(cd->type)) {
		/* If key is not provided, try to use internal key */
		if (!volume_key) {
			if (!cd->volume_key) {
				log_err(cd, _("Volume key does not match the volume."));
				return -EINVAL;
			}
			volume_key_size = cd->volume_key->keylength;
			volume_key = cd->volume_key->key;
		}

		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
		if (!vk)
			return -ENOMEM;
		r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);

		if (r == -EPERM)
			log_err(cd, _("Volume key does not match the volume."));

		if (!r && name)
			r = LUKS1_activate(cd, name, vk, flags);
	} else if (isLUKS2(cd->type)) {
		/* If key is not provided, try to use internal key */
		if (!volume_key) {
			if (!cd->volume_key) {
				log_err(cd, _("Volume key does not match the volume."));
				return -EINVAL;
			}
			volume_key_size = cd->volume_key->keylength;
			volume_key = cd->volume_key->key;
		}

		vk = crypt_alloc_volume_key(volume_key_size, volume_key);
		if (!vk)
			return -ENOMEM;

		r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
		if (r == -EPERM || r == -ENOENT)
			log_err(cd, _("Volume key does not match the volume."));
		if (r > 0)
			r = 0;

		if (!crypt_use_keyring_for_vk(cd))
			use_keyring = false;
		else
			use_keyring = (name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || (flags & CRYPT_ACTIVATE_KEYRING_KEY);

		if (!r && use_keyring) {
			r = LUKS2_key_description_by_segment(cd,
				&cd->u.luks2.hdr, vk, CRYPT_DEFAULT_SEGMENT);
			if (!r)
				r = crypt_volume_key_load_in_keyring(cd, vk);
			if (!r)
				flags |= CRYPT_ACTIVATE_KEYRING_KEY;
		}

		if (!r && name)
			r = LUKS2_activate(cd, name, vk, flags);
	} else if (isVERITY(cd->type)) {
		r = crypt_activate_by_signed_key(cd, name, volume_key, volume_key_size, NULL, 0, flags);
	} else if (isTCRYPT(cd->type)) {
		if (!name)
			return 0;
		r = TCRYPT_activate(cd, name, &cd->u.tcrypt.hdr,
				    &cd->u.tcrypt.params, flags);
	} else if (isINTEGRITY(cd->type)) {
		if (!name)
			return 0;
		if (volume_key) {
			vk = crypt_alloc_volume_key(volume_key_size, volume_key);
			if (!vk)
				return -ENOMEM;
		}
		r = INTEGRITY_activate(cd, name, &cd->u.integrity.params, vk,
				       cd->u.integrity.journal_crypt_key,
				       cd->u.integrity.journal_mac_key, flags,
				       cd->u.integrity.sb_flags);
	} else if (isBITLK(cd->type)) {
		r = BITLK_activate_by_volume_key(cd, name, volume_key, volume_key_size,
						 &cd->u.bitlk.params, flags);
	} else {
		log_err(cd, _("Device type is not properly initialized."));
		r = -EINVAL;
	}

	if (r < 0)
		crypt_drop_keyring_key(cd, vk);
	crypt_free_volume_key(vk);

	return r;
}


int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
	int keyslot, // -1 any
	const char *passphrase,
	size_t passphrase_size,
	const char *new_passphrase,
	size_t new_passphrase_size)
{
	int digest, r, active_slots;
	struct luks2_keyslot_params params;
	struct volume_key *vk = NULL;

	log_dbg(cd, "Adding new keyslot, existing passphrase %sprovided,"
		"new passphrase %sprovided.",
		passphrase ? "" : "not ", new_passphrase  ? "" : "not ");

	if ((r = onlyLUKS(cd)))
		return r;

	if (!passphrase || !new_passphrase)
		return -EINVAL;

	r = keyslot_verify_or_find_empty(cd, &keyslot);
	if (r)
		return r;

	if (isLUKS1(cd->type))
		active_slots = LUKS_keyslot_active_count(&cd->u.luks1.hdr);
	else
		active_slots = LUKS2_keyslot_active_count(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT);
	if (active_slots == 0) {
		/* No slots used, try to use pre-generated key in header */
		if (cd->volume_key) {
			vk = crypt_alloc_volume_key(cd->volume_key->keylength, cd->volume_key->key);
			r = vk ? 0 : -ENOMEM;
		} else {
			log_err(cd, _("Cannot add key slot, all slots disabled and no volume key provided."));
			return -EINVAL;
		}
	} else if (active_slots < 0)
		return -EINVAL;
	else {
		/* Passphrase provided, use it to unlock existing keyslot */
		if (isLUKS1(cd->type))
			r = LUKS_open_key_with_hdr(CRYPT_ANY_SLOT, passphrase,
						   passphrase_size, &cd->u.luks1.hdr, &vk, cd);
		else
			r = LUKS2_keyslot_open(cd, CRYPT_ANY_SLOT, CRYPT_DEFAULT_SEGMENT, passphrase,
						passphrase_size, &vk);
	}

	if (r < 0)
		goto out;

	if (isLUKS1(cd->type))
		r = LUKS_set_key(keyslot, CONST_CAST(char*)new_passphrase,
				 new_passphrase_size, &cd->u.luks1.hdr, vk, cd);
	else {
		r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
		digest = r;

		if (r >= 0)
			r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, &params);

		if (r >= 0)
			r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot, digest, 1, 0);

		if (r >= 0)
			r = LUKS2_keyslot_store(cd,  &cd->u.luks2.hdr, keyslot,
						CONST_CAST(char*)new_passphrase,
						new_passphrase_size, vk, &params);
	}

	if (r < 0)
		goto out;

	r = 0;
out:
	crypt_free_volume_key(vk);
	if (r < 0) {
		_luks2_reload(cd);
		return r;
	}
	return keyslot;
}


static json_object *reencrypt_segment_new(struct luks2_hdr *hdr)
{
	return reencrypt_segment(hdr, 1);
}


static int reencrypt_recovery(struct crypt_device *cd,
		struct luks2_hdr *hdr,
		uint64_t device_size,
		struct volume_key *vks)
{
	int r;
	struct luks2_reencrypt *rh = NULL;

	r = reencrypt_load(cd, hdr, device_size, NULL, vks, &rh);
	if (r < 0) {
		log_err(cd, _("Failed to load LUKS2 reencryption context."));
		return r;
	}

	r = reencrypt_recover_segment(cd, hdr, rh, vks);
	if (r < 0)
		goto out;

	if ((r = reencrypt_assign_segments(cd, hdr, rh, 0, 0)))
		goto out;

	r = reencrypt_context_update(cd, rh);
	if (r) {
		log_err(cd, _("Failed to update reencryption context."));
		goto out;
	}

	r = reencrypt_teardown_ok(cd, hdr, rh);
	if (!r)
		r = LUKS2_hdr_write(cd, hdr);
out:
	LUKS2_reencrypt_free(cd, rh);

	return r;
}


static int _create_device_with_integrity(struct crypt_device *cd,
	const char *type, const char *name, const char *iname,
	const char *ipath, struct crypt_dm_active_device *dmd,
	struct crypt_dm_active_device *dmdi)
{
	int r;
	enum devcheck device_check;
	struct dm_target *tgt;
	struct device *device = NULL;

	if (!single_segment(dmd))
		return -EINVAL;

	tgt = &dmd->segment;
	if (tgt->type != DM_CRYPT)
		return -EINVAL;

	device_check = dmd->flags & CRYPT_ACTIVATE_SHARED ? DEV_OK : DEV_EXCL;

	r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi, 0);
	if (r)
		return r;

	r = device_alloc(cd, &device, ipath);
	if (r < 0)
		goto out;
	tgt->data_device = device;

	r = device_block_adjust(cd, tgt->data_device, device_check,
				tgt->u.crypt.offset, &dmd->size, &dmd->flags);

	if (!r)
		r = dm_create_device(cd, name, type, dmd);
out:
	if (r < 0)
		dm_remove_device(cd, iname, 0);

	device_free(cd, device);
	return r;
}


int crypt_volume_key_get(struct crypt_device *cd,
	int keyslot,
	char *volume_key,
	size_t *volume_key_size,
	const char *passphrase,
	size_t passphrase_size)
{
	struct volume_key *vk = NULL;
	int key_len, r = -EINVAL;

	if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !isVERITY(cd->type) && !passphrase))
		return -EINVAL;

	if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT)
		key_len = LUKS2_get_keyslot_stored_key_size(&cd->u.luks2.hdr, keyslot);
	else
		key_len = crypt_get_volume_key_size(cd);

	if (key_len < 0)
		return -EINVAL;

	if (key_len > (int)*volume_key_size) {
		log_err(cd, _("Volume key buffer too small."));
		return -ENOMEM;
	}

	if (isPLAIN(cd->type) && cd->u.plain.hdr.hash) {
		r = process_key(cd, cd->u.plain.hdr.hash, key_len,
				passphrase, passphrase_size, &vk);
		if (r < 0)
			log_err(cd, _("Cannot retrieve volume key for plain device."));
	} else if (isLUKS1(cd->type)) {
		r = LUKS_open_key_with_hdr(keyslot, passphrase,
					passphrase_size, &cd->u.luks1.hdr, &vk, cd);
	} else if (isLUKS2(cd->type)) {
		r = LUKS2_keyslot_open(cd, keyslot,
				keyslot == CRYPT_ANY_SLOT ? CRYPT_DEFAULT_SEGMENT : CRYPT_ANY_SEGMENT,
				passphrase, passphrase_size, &vk);
	} else if (isTCRYPT(cd->type)) {
		r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk);
	} else if (isVERITY(cd->type)) {
		/* volume_key == root hash */
		if (cd->u.verity.root_hash) {
			memcpy(volume_key, cd->u.verity.root_hash, cd->u.verity.root_hash_size);
			*volume_key_size = cd->u.verity.root_hash_size;
			r = 0;
		} else
			log_err(cd, _("Cannot retrieve root hash for verity device."));
	} else if (isBITLK(cd->type)) {
		r = BITLK_get_volume_key(cd, passphrase, passphrase_size, &cd->u.bitlk.params, &vk);
	} else
		log_err(cd, _("This operation is not supported for %s crypt device."), cd->type ?: "(none)");

	if (r >= 0 && vk) {
		memcpy(volume_key, vk->key, vk->keylength);
		*volume_key_size = vk->keylength;
	}

	crypt_free_volume_key(vk);
	return r;
}


static int _activate_by_passphrase(struct crypt_device *cd,
	const char *name,
	int keyslot,
	const char *passphrase,
	size_t passphrase_size,
	uint32_t flags)
{
	int r;
	struct volume_key *vk = NULL;

	if ((flags & CRYPT_ACTIVATE_KEYRING_KEY) && !crypt_use_keyring_for_vk(cd))
		return -EINVAL;

	if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
		return -EINVAL;

	r = _check_header_data_overlap(cd, name);
	if (r < 0)
		return r;

	if (flags & CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF)
		cd->memory_hard_pbkdf_lock_enabled = true;

	/* plain, use hashed passphrase */
	if (isPLAIN(cd->type)) {
		r = -EINVAL;
		if (!name)
			goto out;

		r = process_key(cd, cd->u.plain.hdr.hash,
				cd->u.plain.key_size,
				passphrase, passphrase_size, &vk);
		if (r < 0)
			goto out;

		r = PLAIN_activate(cd, name, vk, cd->u.plain.hdr.size, flags);
		keyslot = 0;
	} else if (isLUKS1(cd->type)) {
		r = LUKS_open_key_with_hdr(keyslot, passphrase,
					   passphrase_size, &cd->u.luks1.hdr, &vk, cd);
		if (r >= 0) {
			keyslot = r;
			if (name)
				r = LUKS1_activate(cd, name, vk, flags);
		}
	} else if (isLUKS2(cd->type)) {
		r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags);
		keyslot = r;
	} else if (isBITLK(cd->type)) {
		r = BITLK_activate_by_passphrase(cd, name, passphrase, passphrase_size,
						 &cd->u.bitlk.params, flags);
		keyslot = 0;
	} else {
		log_err(cd, _("Device type is not properly initialized."));
		r = -EINVAL;
	}
out:
	if (r < 0)
		crypt_drop_keyring_key(cd, vk);
	crypt_free_volume_key(vk);

	cd->memory_hard_pbkdf_lock_enabled = false;

	return r < 0 ? r : keyslot;
}


int crypt_keyslot_get_key_size(struct crypt_device *cd, int keyslot)
{
	if (!cd || !isLUKS(cd->type))
		return -EINVAL;

	if (keyslot < 0 || keyslot >= crypt_keyslot_max(cd->type))
		return -EINVAL;

	if (isLUKS1(cd->type))
		return cd->u.luks1.hdr.keyBytes;

	if (isLUKS2(cd->type))
		return LUKS2_get_keyslot_stored_key_size(&cd->u.luks2.hdr, keyslot);

	return -EINVAL;
}


int crypt_init(struct crypt_device **cd, const char *device)
{
	struct crypt_device *h = NULL;
	int r;

	if (!cd)
		return -EINVAL;

	log_dbg(NULL, "Allocating context for crypt device %s.", device ?: "(none)");
#if !HAVE_DECL_O_CLOEXEC
	log_dbg(NULL, "Running without O_CLOEXEC.");
#endif

	if (!(h = malloc(sizeof(struct crypt_device))))
		return -ENOMEM;

	memset(h, 0, sizeof(*h));

	r = device_alloc(NULL, &h->device, device);
	if (r < 0) {
		free(h);
		return r;
	}

	dm_backend_init(NULL);

	h->rng_type = crypt_random_default_key_rng();

	*cd = h;
	return 0;
}


libxlDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
{
    libxlDomainObjPrivate *priv;

    priv = g_new0(libxlDomainObjPrivate, 1);

    if (!(priv->devs = virChrdevAlloc())) {
        g_free(priv);
        return NULL;
    }

    if (libxlDomainObjInitJob(priv) < 0) {
        virChrdevFree(priv->devs);
        g_free(priv);
        return NULL;
    }

    return priv;
}


libxlDomainObjInitJob(libxlDomainObjPrivate *priv)
{
    memset(&priv->job, 0, sizeof(priv->job));

    if (virCondInit(&priv->job.cond) < 0)
        return -1;

    priv->job.current = g_new0(virDomainJobInfo, 1);

    return 0;
}


static int __init cgroup_no_v1(char *str)
{
	struct cgroup_subsys *ss;
	char *token;
	int i;

	while ((token = strsep(&str, ",")) != NULL) {
		if (!*token)
			continue;

		if (!strcmp(token, "all")) {
			cgroup_no_v1_mask = U16_MAX;
			continue;
		}

		if (!strcmp(token, "named")) {
			cgroup_no_v1_named = true;
			continue;
		}

		for_each_subsys(ss, i) {
			if (strcmp(token, ss->name) &&
			    strcmp(token, ss->legacy_name))
				continue;

			cgroup_no_v1_mask |= 1 << i;
		}
	}
	return 1;
}


static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos)
{
	/*
	 * Initially we receive a position value that corresponds to
	 * one more than the last pid shown (or 0 on the first call or
	 * after a seek to the start). Use a binary-search to find the
	 * next pid to display, if any
	 */
	struct kernfs_open_file *of = s->private;
	struct cgroup *cgrp = seq_css(s)->cgroup;
	struct cgroup_pidlist *l;
	enum cgroup_filetype type = seq_cft(s)->private;
	int index = 0, pid = *pos;
	int *iter, ret;

	mutex_lock(&cgrp->pidlist_mutex);

	/*
	 * !NULL @of->priv indicates that this isn't the first start()
	 * after open.  If the matching pidlist is around, we can use that.
	 * Look for it.  Note that @of->priv can't be used directly.  It
	 * could already have been destroyed.
	 */
	if (of->priv)
		of->priv = cgroup_pidlist_find(cgrp, type);

	/*
	 * Either this is the first start() after open or the matching
	 * pidlist has been destroyed inbetween.  Create a new one.
	 */
	if (!of->priv) {
		ret = pidlist_array_load(cgrp, type,
					 (struct cgroup_pidlist **)&of->priv);
		if (ret)
			return ERR_PTR(ret);
	}
	l = of->priv;

	if (pid) {
		int end = l->length;

		while (index < end) {
			int mid = (index + end) / 2;
			if (l->list[mid] == pid) {
				index = mid;
				break;
			} else if (l->list[mid] <= pid)
				index = mid + 1;
			else
				end = mid;
		}
	}
	/* If we're off the end of the array, we're done */
	if (index >= l->length)
		return NULL;
	/* Update the abstract position to be the actual pid that we found */
	iter = l->list + index;
	*pos = *iter;
	return iter;
}


static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs,
    int64_t offset, int bytes, BdrvRequestFlags flags)
{
    return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
                                    flags);
}


static inline int64_t mirror_clip_bytes(MirrorBlockJob *s,
                                        int64_t offset,
                                        int64_t bytes)
{
    return MIN(bytes, s->bdev_length - offset);
}


static void mirror_complete(Job *job, Error **errp)
{
    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);

    if (!s->synced) {
        error_setg(errp, "The active block job '%s' cannot be completed",
                   job->id);
        return;
    }

    /* block all operations on to_replace bs */
    if (s->replaces) {
        AioContext *replace_aio_context;

        s->to_replace = bdrv_find_node(s->replaces);
        if (!s->to_replace) {
            error_setg(errp, "Node name '%s' not found", s->replaces);
            return;
        }

        replace_aio_context = bdrv_get_aio_context(s->to_replace);
        aio_context_acquire(replace_aio_context);

        /* TODO Translate this into permission system. Current definition of
         * GRAPH_MOD would require to request it for the parents; they might
         * not even be BlockDriverStates, however, so a BdrvChild can't address
         * them. May need redefinition of GRAPH_MOD. */
        error_setg(&s->replace_blocker,
                   "block device is in use by block-job-complete");
        bdrv_op_block_all(s->to_replace, s->replace_blocker);
        bdrv_ref(s->to_replace);

        aio_context_release(replace_aio_context);
    }

    s->should_complete = true;

    /* If the job is paused, it will be re-entered when it is resumed */
    if (!job->paused) {
        job_enter(job);
    }
}


static MirrorOp *coroutine_fn active_write_prepare(MirrorBlockJob *s,
                                                   uint64_t offset,
                                                   uint64_t bytes)
{
    MirrorOp *op;
    uint64_t start_chunk = offset / s->granularity;
    uint64_t end_chunk = DIV_ROUND_UP(offset + bytes, s->granularity);

    op = g_new(MirrorOp, 1);
    *op = (MirrorOp){
        .s                  = s,
        .offset             = offset,
        .bytes              = bytes,
        .is_active_write    = true,
        .is_in_flight       = true,
        .co                 = qemu_coroutine_self(),
    };
    qemu_co_queue_init(&op->waiting_requests);
    QTAILQ_INSERT_TAIL(&s->ops_in_flight, op, next);

    s->in_active_write_counter++;

    mirror_wait_on_conflicts(op, s, offset, bytes);

    bitmap_set(s->in_flight_bitmap, start_chunk, end_chunk - start_chunk);

    return op;
}


static void mirror_abort(Job *job)
{
    int ret = mirror_exit_common(job);
    assert(ret == 0);
}


static void coroutine_fn mirror_co_discard(void *opaque)
{
    MirrorOp *op = opaque;
    int ret;

    op->s->in_flight++;
    op->s->bytes_in_flight += op->bytes;
    *op->bytes_handled = op->bytes;
    op->is_in_flight = true;

    ret = blk_co_pdiscard(op->s->target, op->offset, op->bytes);
    mirror_write_complete(op, ret);
}


static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
                            uint64_t *bytes)
{
    bool need_cow;
    int ret = 0;
    int64_t align_offset = *offset;
    int64_t align_bytes = *bytes;
    int max_bytes = s->granularity * s->max_iov;

    need_cow = !test_bit(*offset / s->granularity, s->cow_bitmap);
    need_cow |= !test_bit((*offset + *bytes - 1) / s->granularity,
                          s->cow_bitmap);
    if (need_cow) {
        bdrv_round_to_clusters(blk_bs(s->target), *offset, *bytes,
                               &align_offset, &align_bytes);
    }

    if (align_bytes > max_bytes) {
        align_bytes = max_bytes;
        if (need_cow) {
            align_bytes = QEMU_ALIGN_DOWN(align_bytes, s->target_cluster_size);
        }
    }
    /* Clipping may result in align_bytes unaligned to chunk boundary, but
     * that doesn't matter because it's already the end of source image. */
    align_bytes = mirror_clip_bytes(s, align_offset, align_bytes);

    ret = align_offset + align_bytes - (*offset + *bytes);
    *offset = align_offset;
    *bytes = align_bytes;
    assert(ret >= 0);
    return ret;
}


static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset,
                               unsigned bytes, MirrorMethod mirror_method)
{
    MirrorOp *op;
    Coroutine *co;
    int64_t bytes_handled = -1;

    op = g_new(MirrorOp, 1);
    *op = (MirrorOp){
        .s              = s,
        .offset         = offset,
        .bytes          = bytes,
        .bytes_handled  = &bytes_handled,
    };
    qemu_co_queue_init(&op->waiting_requests);

    switch (mirror_method) {
    case MIRROR_METHOD_COPY:
        co = qemu_coroutine_create(mirror_co_read, op);
        break;
    case MIRROR_METHOD_ZERO:
        co = qemu_coroutine_create(mirror_co_zero, op);
        break;
    case MIRROR_METHOD_DISCARD:
        co = qemu_coroutine_create(mirror_co_discard, op);
        break;
    default:
        abort();
    }
    op->co = co;

    QTAILQ_INSERT_TAIL(&s->ops_in_flight, op, next);
    qemu_coroutine_enter(co);
    /* At this point, ownership of op has been moved to the coroutine
     * and the object may already be freed */

    /* Assert that this value has been set */
    assert(bytes_handled >= 0);

    /* Same assertion as in mirror_co_read() (and for mirror_co_read()
     * and mirror_co_discard(), bytes_handled == op->bytes, which
     * is the @bytes parameter given to this function) */
    assert(bytes_handled <= UINT_MAX);
    return bytes_handled;
}


static BlockErrorAction mirror_error_action(MirrorBlockJob *s, bool read,
                                            int error)
{
    s->synced = false;
    s->actively_synced = false;
    if (read) {
        return block_job_error_action(&s->common, s->on_source_error,
                                      true, error);
    } else {
        return block_job_error_action(&s->common, s->on_target_error,
                                      false, error);
    }
}


static int coroutine_fn mirror_run(Job *job, Error **errp)
{
    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
    BlockDriverState *bs = s->mirror_top_bs->backing->bs;
    BlockDriverState *target_bs = blk_bs(s->target);
    bool need_drain = true;
    int64_t length;
    int64_t target_length;
    BlockDriverInfo bdi;
    char backing_filename[2]; /* we only need 2 characters because we are only
                                 checking for a NULL string */
    int ret = 0;

    if (job_is_cancelled(&s->common.job)) {
        goto immediate_exit;
    }

    s->bdev_length = bdrv_getlength(bs);
    if (s->bdev_length < 0) {
        ret = s->bdev_length;
        goto immediate_exit;
    }

    target_length = blk_getlength(s->target);
    if (target_length < 0) {
        ret = target_length;
        goto immediate_exit;
    }

    /* Active commit must resize the base image if its size differs from the
     * active layer. */
    if (s->base == blk_bs(s->target)) {
        if (s->bdev_length > target_length) {
            ret = blk_truncate(s->target, s->bdev_length, false,
                               PREALLOC_MODE_OFF, 0, NULL);
            if (ret < 0) {
                goto immediate_exit;
            }
        }
    } else if (s->bdev_length != target_length) {
        error_setg(errp, "Source and target image have different sizes");
        ret = -EINVAL;
        goto immediate_exit;
    }

    if (s->bdev_length == 0) {
        /* Transition to the READY state and wait for complete. */
        job_transition_to_ready(&s->common.job);
        s->synced = true;
        s->actively_synced = true;
        while (!job_is_cancelled(&s->common.job) && !s->should_complete) {
            job_yield(&s->common.job);
        }
        s->common.job.cancelled = false;
        goto immediate_exit;
    }

    length = DIV_ROUND_UP(s->bdev_length, s->granularity);
    s->in_flight_bitmap = bitmap_new(length);

    /* If we have no backing file yet in the destination, we cannot let
     * the destination do COW.  Instead, we copy sectors around the
     * dirty data if needed.  We need a bitmap to do that.
     */
    bdrv_get_backing_filename(target_bs, backing_filename,
                              sizeof(backing_filename));
    if (!bdrv_get_info(target_bs, &bdi) && bdi.cluster_size) {
        s->target_cluster_size = bdi.cluster_size;
    } else {
        s->target_cluster_size = BDRV_SECTOR_SIZE;
    }
    if (backing_filename[0] && !bdrv_backing_chain_next(target_bs) &&
        s->granularity < s->target_cluster_size) {
        s->buf_size = MAX(s->buf_size, s->target_cluster_size);
        s->cow_bitmap = bitmap_new(length);
    }
    s->max_iov = MIN(bs->bl.max_iov, target_bs->bl.max_iov);

    s->buf = qemu_try_blockalign(bs, s->buf_size);
    if (s->buf == NULL) {
        ret = -ENOMEM;
        goto immediate_exit;
    }

    mirror_free_init(s);

    s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
    if (!s->is_none_mode) {
        ret = mirror_dirty_init(s);
        if (ret < 0 || job_is_cancelled(&s->common.job)) {
            goto immediate_exit;
        }
    }

    assert(!s->dbi);
    s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
    for (;;) {
        uint64_t delay_ns = 0;
        int64_t cnt, delta;
        bool should_complete;

        /* Do not start passive operations while there are active
         * writes in progress */
        while (s->in_active_write_counter) {
            mirror_wait_for_any_operation(s, true);
        }

        if (s->ret < 0) {
            ret = s->ret;
            goto immediate_exit;
        }

        job_pause_point(&s->common.job);

        cnt = bdrv_get_dirty_count(s->dirty_bitmap);
        /* cnt is the number of dirty bytes remaining and s->bytes_in_flight is
         * the number of bytes currently being processed; together those are
         * the current remaining operation length */
        job_progress_set_remaining(&s->common.job, s->bytes_in_flight + cnt);

        /* Note that even when no rate limit is applied we need to yield
         * periodically with no pending I/O so that bdrv_drain_all() returns.
         * We do so every BLKOCK_JOB_SLICE_TIME nanoseconds, or when there is
         * an error, or when the source is clean, whichever comes first. */
        delta = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->last_pause_ns;
        if (delta < BLOCK_JOB_SLICE_TIME &&
            s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
            if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
                (cnt == 0 && s->in_flight > 0)) {
                trace_mirror_yield(s, cnt, s->buf_free_count, s->in_flight);
                mirror_wait_for_free_in_flight_slot(s);
                continue;
            } else if (cnt != 0) {
                delay_ns = mirror_iteration(s);
            }
        }

        should_complete = false;
        if (s->in_flight == 0 && cnt == 0) {
            trace_mirror_before_flush(s);
            if (!s->synced) {
                if (mirror_flush(s) < 0) {
                    /* Go check s->ret.  */
                    continue;
                }
                /* We're out of the streaming phase.  From now on, if the job
                 * is cancelled we will actually complete all pending I/O and
                 * report completion.  This way, block-job-cancel will leave
                 * the target in a consistent state.
                 */
                job_transition_to_ready(&s->common.job);
                s->synced = true;
                if (s->copy_mode != MIRROR_COPY_MODE_BACKGROUND) {
                    s->actively_synced = true;
                }
            }

            should_complete = s->should_complete ||
                job_is_cancelled(&s->common.job);
            cnt = bdrv_get_dirty_count(s->dirty_bitmap);
        }

        if (cnt == 0 && should_complete) {
            /* The dirty bitmap is not updated while operations are pending.
             * If we're about to exit, wait for pending operations before
             * calling bdrv_get_dirty_count(bs), or we may exit while the
             * source has dirty data to copy!
             *
             * Note that I/O can be submitted by the guest while
             * mirror_populate runs, so pause it now.  Before deciding
             * whether to switch to target check one last time if I/O has
             * come in the meanwhile, and if not flush the data to disk.
             */
            trace_mirror_before_drain(s, cnt);

            s->in_drain = true;
            bdrv_drained_begin(bs);
            cnt = bdrv_get_dirty_count(s->dirty_bitmap);
            if (cnt > 0 || mirror_flush(s) < 0) {
                bdrv_drained_end(bs);
                s->in_drain = false;
                continue;
            }

            /* The two disks are in sync.  Exit and report successful
             * completion.
             */
            assert(QLIST_EMPTY(&bs->tracked_requests));
            s->common.job.cancelled = false;
            need_drain = false;
            break;
        }

        ret = 0;

        if (s->synced && !should_complete) {
            delay_ns = (s->in_flight == 0 &&
                        cnt == 0 ? BLOCK_JOB_SLICE_TIME : 0);
        }
        trace_mirror_before_sleep(s, cnt, s->synced, delay_ns);
        job_sleep_ns(&s->common.job, delay_ns);
        if (job_is_cancelled(&s->common.job) &&
            (!s->synced || s->common.job.force_cancel))
        {
            break;
        }
        s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
    }

immediate_exit:
    if (s->in_flight > 0) {
        /* We get here only if something went wrong.  Either the job failed,
         * or it was cancelled prematurely so that we do not guarantee that
         * the target is a copy of the source.
         */
        assert(ret < 0 || ((s->common.job.force_cancel || !s->synced) &&
               job_is_cancelled(&s->common.job)));
        assert(need_drain);
        mirror_wait_for_all_io(s);
    }

    assert(s->in_flight == 0);
    qemu_vfree(s->buf);
    g_free(s->cow_bitmap);
    g_free(s->in_flight_bitmap);
    bdrv_dirty_iter_free(s->dbi);

    if (need_drain) {
        s->in_drain = true;
        bdrv_drained_begin(bs);
    }

    return ret;
}


void addDbAdminDbPrivileges(PrivilegeVector* privileges, StringData dbName) {
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forDatabaseName(dbName), dbAdminRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.indexes")),
                  readRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.namespaces")),
                  readRoleActions));

    ActionSet profileActions = readRoleActions;
    profileActions.addAction(ActionType::convertToCapped);
    profileActions.addAction(ActionType::createCollection);
    profileActions.addAction(ActionType::dropCollection);
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.profile")),
                  profileActions));
}


void addBackupPrivileges(PrivilegeVector* privileges) {
    ActionSet clusterActions;
    clusterActions << ActionType::appendOplogNote;  // For BRS
    clusterActions << ActionType::serverStatus;     // For push based initial sync
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forClusterResource(), clusterActions));

    ActionSet configSettingsActions;
    configSettingsActions << ActionType::insert << ActionType::update;
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forExactNamespace(NamespaceString("config", "settings")),
                  configSettingsActions));

    addQueryableBackupPrivileges(privileges);
}


MONGO_INITIALIZER(AuthorizationBuiltinRoles)(InitializerContext* context) {
    // Read role
    readRoleActions
        << ActionType::changeStream
        << ActionType::collStats
        << ActionType::dbHash
        << ActionType::dbStats
        << ActionType::find
        << ActionType::killCursors
        << ActionType::listCollections
        << ActionType::listIndexes
        << ActionType::planCacheRead;

    // Read-write role
    readWriteRoleActions += readRoleActions;
    readWriteRoleActions
        << ActionType::convertToCapped  // db admin gets this also
        << ActionType::createCollection  // db admin gets this also
        << ActionType::dropCollection
        << ActionType::dropIndex
        << ActionType::emptycapped
        << ActionType::createIndex
        << ActionType::insert
        << ActionType::remove
        << ActionType::renameCollectionSameDB  // db admin gets this also
        << ActionType::update;

    // User admin role
    userAdminRoleActions
        << ActionType::changeCustomData
        << ActionType::changePassword
        << ActionType::createUser
        << ActionType::createRole
        << ActionType::dropUser
        << ActionType::dropRole
        << ActionType::grantRole
        << ActionType::revokeRole
        << ActionType::setAuthenticationRestriction
        << ActionType::viewUser
        << ActionType::viewRole;

    // DB admin role
    dbAdminRoleActions
        << ActionType::bypassDocumentValidation
        << ActionType::collMod
        << ActionType::collStats  // clusterMonitor gets this also
        << ActionType::compact
        << ActionType::convertToCapped  // read_write gets this also
        << ActionType::createCollection // read_write gets this also
        << ActionType::dbStats  // clusterMonitor gets this also
        << ActionType::dropCollection
        << ActionType::dropDatabase  // clusterAdmin gets this also TODO(spencer): should
                                     // readWriteAnyDatabase?
        << ActionType::dropIndex
        << ActionType::createIndex
        << ActionType::enableProfiler
        << ActionType::listCollections
        << ActionType::listIndexes
        << ActionType::planCacheIndexFilter
        << ActionType::planCacheRead
        << ActionType::planCacheWrite
        << ActionType::reIndex
        << ActionType::renameCollectionSameDB  // read_write gets this also
        << ActionType::storageDetails
        << ActionType::validate;

    // clusterMonitor role actions that target the cluster resource
    clusterMonitorRoleClusterActions
        << ActionType::checkFreeMonitoringStatus
        << ActionType::connPoolStats
        << ActionType::getCmdLineOpts
        << ActionType::getLog
        << ActionType::getParameter
        << ActionType::getShardMap
        << ActionType::hostInfo
        << ActionType::listDatabases
        << ActionType::listSessions // clusterManager gets this also
        << ActionType::listShards  // clusterManager gets this also
        << ActionType::netstat
        << ActionType::replSetGetConfig  // clusterManager gets this also
        << ActionType::replSetGetStatus  // clusterManager gets this also
        << ActionType::serverStatus
        << ActionType::top
        << ActionType::useUUID
        << ActionType::inprog
        << ActionType::shardingState;

    // clusterMonitor role actions that target a database (or collection) resource
    clusterMonitorRoleDatabaseActions
        << ActionType::collStats  // dbAdmin gets this also
        << ActionType::dbStats  // dbAdmin gets this also
        << ActionType::getDatabaseVersion
        << ActionType::getShardVersion
        << ActionType::indexStats;

    // hostManager role actions that target the cluster resource
    hostManagerRoleClusterActions
        << ActionType::applicationMessage  // clusterManager gets this also
        << ActionType::connPoolSync
        << ActionType::cpuProfiler
        << ActionType::dropConnections
        << ActionType::logRotate
        << ActionType::setParameter
        << ActionType::shutdown
        << ActionType::touch
        << ActionType::unlock
        << ActionType::flushRouterConfig  // clusterManager gets this also
        << ActionType::fsync
        << ActionType::invalidateUserCache // userAdminAnyDatabase gets this also
        << ActionType::killAnyCursor
        << ActionType::killAnySession
        << ActionType::killop
        << ActionType::replSetResizeOplog
        << ActionType::resync  // clusterManager gets this also
        << ActionType::trafficRecord;

    // hostManager role actions that target the database resource
    hostManagerRoleDatabaseActions
        << ActionType::killCursors;

    // clusterManager role actions that target the cluster resource
    clusterManagerRoleClusterActions
        << ActionType::appendOplogNote  // backup gets this also
        << ActionType::applicationMessage  // hostManager gets this also
        << ActionType::replSetConfigure
        << ActionType::replSetGetConfig  // clusterMonitor gets this also
        << ActionType::replSetGetStatus  // clusterMonitor gets this also
        << ActionType::replSetStateChange
        << ActionType::resync  // hostManager gets this also
        << ActionType::addShard
        << ActionType::removeShard
        << ActionType::listSessions  // clusterMonitor gets this also
        << ActionType::listShards  // clusterMonitor gets this also
        << ActionType::flushRouterConfig  // hostManager gets this also
        << ActionType::cleanupOrphaned
        << ActionType::setFeatureCompatibilityVersion
        << ActionType::setFreeMonitoring;

    clusterManagerRoleDatabaseActions
        << ActionType::clearJumboFlag
        << ActionType::splitChunk
        << ActionType::moveChunk
        << ActionType::enableSharding
        << ActionType::splitVector;

    return Status::OK();
}


void addUserAdminAnyDbPrivileges(PrivilegeVector* privileges) {
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forAnyNormalResource(), userAdminRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forDatabaseName("local"), userAdminRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forDatabaseName("config"), userAdminRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forClusterResource(), ActionType::listDatabases));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forClusterResource(), ActionType::authSchemaUpgrade));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forClusterResource(), ActionType::invalidateUserCache));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forClusterResource(), ActionType::viewUser));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forAnyNormalResource(), ActionType::listCachedAndActiveUsers));

    ActionSet readRoleAndIndexActions;
    readRoleAndIndexActions += readRoleActions;
    readRoleAndIndexActions << ActionType::createIndex << ActionType::dropIndex;

    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forCollectionName("system.users"), readRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(
            ResourcePattern::forExactNamespace(AuthorizationManager::usersCollectionNamespace),
            readRoleAndIndexActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(
            ResourcePattern::forExactNamespace(AuthorizationManager::rolesCollectionNamespace),
            readRoleAndIndexActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(
            ResourcePattern::forExactNamespace(AuthorizationManager::versionCollectionNamespace),
            readRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(
            ResourcePattern::forExactNamespace(AuthorizationManager::usersAltCollectionNamespace),
            readRoleActions));
    Privilege::addPrivilegeToPrivilegeVector(
        privileges,
        Privilege(ResourcePattern::forExactNamespace(
                      AuthorizationManager::usersBackupCollectionNamespace),
                  readRoleActions));
}


void addEnableShardingPrivileges(PrivilegeVector* privileges) {
    ActionSet enableShardingActions;
    enableShardingActions.addAction(ActionType::enableSharding);
    enableShardingActions.addAction(ActionType::refineCollectionShardKey);
    Privilege::addPrivilegeToPrivilegeVector(
        privileges, Privilege(ResourcePattern::forAnyNormalResource(), enableShardingActions));
}


get_bounding_box (GeglOperation *operation)
{
  GeglRectangle result = {0,0,0,0};
  GeglProperties   *o = GEGL_PROPERTIES (operation);
  gint width, height;

  load_cache (o);

  g_object_get (o->user_data, "width", &width,
                               "height", &height, NULL);
  result.width  = width;
  result.height = height;
  return result;
}


static int match_idx(struct device *d, const void *data)
{
	struct nfc_dev *dev = to_nfc_dev(d);
	const unsigned int *idx = data;

	return dev->idx == *idx;
}


int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type)
{
	struct nfc_se *se;
	int rc;

	pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx);

	se = nfc_find_se(dev, se_idx);
	if (se)
		return -EALREADY;

	se = kzalloc(sizeof(struct nfc_se), GFP_KERNEL);
	if (!se)
		return -ENOMEM;

	se->idx = se_idx;
	se->type = type;
	se->state = NFC_SE_DISABLED;
	INIT_LIST_HEAD(&se->list);

	list_add(&se->list, &dev->secure_elements);

	rc = nfc_genl_se_added(dev, se_idx, type);
	if (rc < 0) {
		list_del(&se->list);
		kfree(se);

		return rc;
	}

	return 0;
}


int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
{
	const struct nfc_target *tg;
	int i;

	pr_debug("dev_name %s n_target %d\n", dev_name(&dev->dev), target_idx);

	device_lock(&dev->dev);

	for (i = 0; i < dev->n_targets; i++) {
		tg = &dev->targets[i];
		if (tg->idx == target_idx)
			break;
	}

	if (i == dev->n_targets) {
		device_unlock(&dev->dev);
		return -EINVAL;
	}

	dev->targets_generation++;
	dev->n_targets--;
	dev->active_target = NULL;

	if (dev->n_targets) {
		memcpy(&dev->targets[i], &dev->targets[i + 1],
		       (dev->n_targets - i) * sizeof(struct nfc_target));
	} else {
		kfree(dev->targets);
		dev->targets = NULL;
	}

	device_unlock(&dev->dev);

	nfc_genl_target_lost(dev, target_idx);

	return 0;
}


struct nfc_dev *nfc_allocate_device(const struct nfc_ops *ops,
				    u32 supported_protocols,
				    int tx_headroom, int tx_tailroom)
{
	struct nfc_dev *dev;
	int rc;

	if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
	    !ops->deactivate_target || !ops->im_transceive)
		return NULL;

	if (!supported_protocols)
		return NULL;

	dev = kzalloc(sizeof(struct nfc_dev), GFP_KERNEL);
	if (!dev)
		return NULL;

	rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
	if (rc < 0)
		goto err_free_dev;
	dev->idx = rc;

	dev->dev.class = &nfc_class;
	dev_set_name(&dev->dev, "nfc%d", dev->idx);
	device_initialize(&dev->dev);

	dev->ops = ops;
	dev->supported_protocols = supported_protocols;
	dev->tx_headroom = tx_headroom;
	dev->tx_tailroom = tx_tailroom;
	INIT_LIST_HEAD(&dev->secure_elements);

	nfc_genl_data_init(&dev->genl_data);

	dev->rf_mode = NFC_RF_NONE;

	/* first generation must not be 0 */
	dev->targets_generation = 1;

	if (ops->check_presence) {
		timer_setup(&dev->check_pres_timer, nfc_check_pres_timeout, 0);
		INIT_WORK(&dev->check_pres_work, nfc_check_pres_work);
	}

	return dev;

err_free_dev:
	kfree(dev);

	return NULL;
}


void nci_free_device(struct nci_dev *ndev)
{
	nfc_free_device(ndev->nfc_dev);
	nci_hci_deallocate(ndev);
	kfree(ndev);
}


int nci_core_ntf_packet(struct nci_dev *ndev, __u16 opcode,
			struct sk_buff *skb)
{
	return nci_op_ntf_packet(ndev, opcode, skb, ndev->ops->core_ops,
				 ndev->ops->n_core_ops);
}


static int unix_socketpair(struct socket *socka, struct socket *sockb)
{
	struct sock *ska = socka->sk, *skb = sockb->sk;

	/* Join our sockets back to back */
	sock_hold(ska);
	sock_hold(skb);
	unix_peer(ska) = skb;
	unix_peer(skb) = ska;
	init_peercred(ska);
	init_peercred(skb);

	ska->sk_state = TCP_ESTABLISHED;
	skb->sk_state = TCP_ESTABLISHED;
	socka->state  = SS_CONNECTED;
	sockb->state  = SS_CONNECTED;
	return 0;
}


void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
{
	if (del_timer_sync(timer))
		__sock_put(sk);
}


static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other)
{
	struct unix_sock *ousk = unix_sk(other);
	struct sk_buff *skb;
	int err = 0;

	skb = sock_alloc_send_skb(sock->sk, 1, msg->msg_flags & MSG_DONTWAIT, &err);

	if (!skb)
		return err;

	skb_put(skb, 1);
	err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, 1);

	if (err) {
		kfree_skb(skb);
		return err;
	}

	unix_state_lock(other);

	if (sock_flag(other, SOCK_DEAD) ||
	    (other->sk_shutdown & RCV_SHUTDOWN)) {
		unix_state_unlock(other);
		kfree_skb(skb);
		return -EPIPE;
	}

	maybe_add_creds(skb, sock, other);
	skb_get(skb);

	if (ousk->oob_skb)
		consume_skb(ousk->oob_skb);

	ousk->oob_skb = skb;

	scm_stat_add(other, skb);
	skb_queue_tail(&other->sk_receive_queue, skb);
	sk_send_sigurg(other);
	unix_state_unlock(other);
	other->sk_data_ready(other);

	return err;
}