Ejemplo n.º 1
0
/* Execute a getfsmap query against the realtime device. */
STATIC int
__xfs_getfsmap_rtdev(
	struct xfs_trans		*tp,
	struct xfs_fsmap		*keys,
	int				(*query_fn)(struct xfs_trans *,
						    struct xfs_getfsmap_info *),
	struct xfs_getfsmap_info	*info)
{
	struct xfs_mount		*mp = tp->t_mountp;
	xfs_fsblock_t			start_fsb;
	xfs_fsblock_t			end_fsb;
	xfs_daddr_t			eofs;
	int				error = 0;

	eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
	if (keys[0].fmr_physical >= eofs)
		return 0;
	if (keys[1].fmr_physical >= eofs)
		keys[1].fmr_physical = eofs - 1;
	start_fsb = XFS_BB_TO_FSBT(mp, keys[0].fmr_physical);
	end_fsb = XFS_BB_TO_FSB(mp, keys[1].fmr_physical);

	/* Set up search keys */
	info->low.rm_startblock = start_fsb;
	error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]);
	if (error)
		return error;
	info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset);
	info->low.rm_blockcount = 0;
	xfs_getfsmap_set_irec_flags(&info->low, &keys[0]);

	info->high.rm_startblock = end_fsb;
	error = xfs_fsmap_owner_to_rmap(&info->high, &keys[1]);
	if (error)
		return error;
	info->high.rm_offset = XFS_BB_TO_FSBT(mp, keys[1].fmr_offset);
	info->high.rm_blockcount = 0;
	xfs_getfsmap_set_irec_flags(&info->high, &keys[1]);

	trace_xfs_fsmap_low_key(mp, info->dev, info->agno, &info->low);
	trace_xfs_fsmap_high_key(mp, info->dev, info->agno, &info->high);

	return query_fn(tp, info);
}
Ejemplo n.º 2
0
/* Execute a getfsmap query against the regular data device. */
STATIC int
__xfs_getfsmap_datadev(
	struct xfs_trans		*tp,
	struct xfs_fsmap		*keys,
	struct xfs_getfsmap_info	*info,
	int				(*query_fn)(struct xfs_trans *,
						    struct xfs_getfsmap_info *,
						    struct xfs_btree_cur **,
						    void *),
	void				*priv)
{
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_btree_cur		*bt_cur = NULL;
	xfs_fsblock_t			start_fsb;
	xfs_fsblock_t			end_fsb;
	xfs_agnumber_t			start_ag;
	xfs_agnumber_t			end_ag;
	xfs_daddr_t			eofs;
	int				error = 0;

	eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
	if (keys[0].fmr_physical >= eofs)
		return 0;
	if (keys[1].fmr_physical >= eofs)
		keys[1].fmr_physical = eofs - 1;
	start_fsb = XFS_DADDR_TO_FSB(mp, keys[0].fmr_physical);
	end_fsb = XFS_DADDR_TO_FSB(mp, keys[1].fmr_physical);

	/*
	 * Convert the fsmap low/high keys to AG based keys.  Initialize
	 * low to the fsmap low key and max out the high key to the end
	 * of the AG.
	 */
	info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
	info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset);
	error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]);
	if (error)
		return error;
	info->low.rm_blockcount = 0;
	xfs_getfsmap_set_irec_flags(&info->low, &keys[0]);

	info->high.rm_startblock = -1U;
	info->high.rm_owner = ULLONG_MAX;
	info->high.rm_offset = ULLONG_MAX;
	info->high.rm_blockcount = 0;
	info->high.rm_flags = XFS_RMAP_KEY_FLAGS | XFS_RMAP_REC_FLAGS;

	start_ag = XFS_FSB_TO_AGNO(mp, start_fsb);
	end_ag = XFS_FSB_TO_AGNO(mp, end_fsb);

	/* Query each AG */
	for (info->agno = start_ag; info->agno <= end_ag; info->agno++) {
		/*
		 * Set the AG high key from the fsmap high key if this
		 * is the last AG that we're querying.
		 */
		if (info->agno == end_ag) {
			info->high.rm_startblock = XFS_FSB_TO_AGBNO(mp,
					end_fsb);
			info->high.rm_offset = XFS_BB_TO_FSBT(mp,
					keys[1].fmr_offset);
			error = xfs_fsmap_owner_to_rmap(&info->high, &keys[1]);
			if (error)
				goto err;
			xfs_getfsmap_set_irec_flags(&info->high, &keys[1]);
		}

		if (bt_cur) {
			xfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR);
			bt_cur = NULL;
			xfs_trans_brelse(tp, info->agf_bp);
			info->agf_bp = NULL;
		}

		error = xfs_alloc_read_agf(mp, tp, info->agno, 0,
				&info->agf_bp);
		if (error)
			goto err;

		trace_xfs_fsmap_low_key(mp, info->dev, info->agno, &info->low);
		trace_xfs_fsmap_high_key(mp, info->dev, info->agno,
				&info->high);

		error = query_fn(tp, info, &bt_cur, priv);
		if (error)
			goto err;

		/*
		 * Set the AG low key to the start of the AG prior to
		 * moving on to the next AG.
		 */
		if (info->agno == start_ag) {
			info->low.rm_startblock = 0;
			info->low.rm_owner = 0;
			info->low.rm_offset = 0;
			info->low.rm_flags = 0;
		}
	}

	/* Report any gap at the end of the AG */
	info->last = true;
	error = query_fn(tp, info, &bt_cur, priv);
	if (error)
		goto err;

err:
	if (bt_cur)
		xfs_btree_del_cursor(bt_cur, error < 0 ? XFS_BTREE_ERROR :
							 XFS_BTREE_NOERROR);
	if (info->agf_bp) {
		xfs_trans_brelse(tp, info->agf_bp);
		info->agf_bp = NULL;
	}

	return error;
}
Ejemplo n.º 3
0
static void timer_send_full_state_notifies(int round)
{
	db_key_t query_cols[1], result_cols[22], update_cols[1];
	db_val_t query_vals[1], update_vals[1], *values;
	db_row_t *rows;
	db1_res_t *result = NULL;
	int n_result_cols = 0, i;
	int pres_uri_col, tuser_col, tdomain_col, fuser_col, fdomain_col;
	int wuser_col, wdomain_col, callid_col, to_tag_col, from_tag_col;
	int sockinfo_col, lcontact_col, contact_col, rroute_col, event_id_col;
	int reason_col, event_col, lcseq_col, rcseq_col, status_col;
	int version_col, expires_col;
	subs_t sub;
	str ev_sname;
	event_t parsed_event;
	xmlDocPtr doc = NULL;
	xmlNodePtr service_node = NULL;
	int now = (int)time(NULL);
	db_query_f query_fn = rls_dbf.query_lock ? rls_dbf.query_lock : rls_dbf.query;

	query_cols[0] = &str_updated_col;
	query_vals[0].type = DB1_INT;
	query_vals[0].nul = 0;
	query_vals[0].val.int_val = round;

	result_cols[pres_uri_col = n_result_cols++] = &str_presentity_uri_col;
	result_cols[tuser_col = n_result_cols++] = &str_to_user_col;
	result_cols[tdomain_col = n_result_cols++] = &str_to_domain_col;
	result_cols[fuser_col = n_result_cols++] = &str_from_user_col;
	result_cols[fdomain_col = n_result_cols++] = &str_from_domain_col;
	result_cols[wuser_col = n_result_cols++] = &str_watcher_username_col;
	result_cols[wdomain_col = n_result_cols++] = &str_watcher_domain_col;
	result_cols[callid_col = n_result_cols++] = &str_callid_col;
	result_cols[to_tag_col = n_result_cols++] = &str_to_tag_col;
	result_cols[from_tag_col = n_result_cols++] = &str_from_tag_col;
	result_cols[sockinfo_col = n_result_cols++] = &str_socket_info_col;
	result_cols[lcontact_col = n_result_cols++] = &str_local_contact_col;
	result_cols[contact_col = n_result_cols++] = &str_contact_col;
	result_cols[rroute_col = n_result_cols++] = &str_record_route_col;
	result_cols[event_id_col = n_result_cols++] = &str_event_id_col;
	result_cols[reason_col = n_result_cols++] = &str_reason_col;
	result_cols[event_col = n_result_cols++] = &str_event_col;
	result_cols[lcseq_col = n_result_cols++] = &str_local_cseq_col;
	result_cols[rcseq_col = n_result_cols++] = &str_remote_cseq_col;
	result_cols[status_col = n_result_cols++] = &str_status_col;
	result_cols[version_col = n_result_cols++] = &str_version_col;
	result_cols[expires_col = n_result_cols++] = &str_expires_col;

	update_cols[0] = &str_updated_col;
	update_vals[0].type = DB1_INT;
	update_vals[0].nul = 0;
	update_vals[0].val.int_val = NO_UPDATE_TYPE;

	if (rls_dbf.use_table(rls_db, &rlsubs_table) < 0)
	{
		LM_ERR("use table failed\n");
		goto done;
	}

	if (dbmode == RLS_DB_ONLY && rls_dbf.start_transaction)
	{
		if (rls_dbf.start_transaction(rls_db, DB_LOCKING_WRITE) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto done;
		}
	}

	/* Step 1: Find rls_watchers that require full-state notification */
	if (query_fn(rls_db, query_cols, 0, query_vals, result_cols,
				1, n_result_cols, 0, &result) < 0)
	{
		LM_ERR("in sql query\n");
		goto done;
	}
	if(result== NULL || result->n<= 0)
		goto done;

	/* Step 2: Reset the update flag so we do not full-state notify
 	   these watchers again */
	if(rls_dbf.update(rls_db, query_cols, 0, query_vals, update_cols,
					update_vals, 1, 1)< 0)
	{
		LM_ERR("in sql update\n");
		goto done;
	}

	if (dbmode == RLS_DB_ONLY && rls_dbf.end_transaction)
	{
		if (rls_dbf.end_transaction(rls_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto done;
		}
	}

	/* Step 3: Full-state notify each watcher we found */
	rows = RES_ROWS(result);
	for (i = 0; i < RES_ROW_N(result); i++)
	{
		memset(&sub, 0, sizeof(subs_t));
		values = ROW_VALUES(&rows[i]);
		EXTRACT_STRING(sub.pres_uri, VAL_STRING(&values[pres_uri_col]));
		EXTRACT_STRING(sub.to_user, VAL_STRING(&values[tuser_col]));
		EXTRACT_STRING(sub.to_domain, VAL_STRING(&values[tdomain_col]));
		EXTRACT_STRING(sub.from_user, VAL_STRING(&values[fuser_col]));
		EXTRACT_STRING(sub.from_domain, VAL_STRING(&values[fdomain_col]));
		EXTRACT_STRING(sub.watcher_user, VAL_STRING(&values[wuser_col]));
		EXTRACT_STRING(sub.watcher_domain, VAL_STRING(&values[wdomain_col]));
		EXTRACT_STRING(sub.callid, VAL_STRING(&values[callid_col]));
		EXTRACT_STRING(sub.to_tag, VAL_STRING(&values[to_tag_col]));
		EXTRACT_STRING(sub.from_tag, VAL_STRING(&values[from_tag_col]));
		EXTRACT_STRING(sub.sockinfo_str, VAL_STRING(&values[sockinfo_col]));
		EXTRACT_STRING(sub.local_contact, VAL_STRING(&values[lcontact_col]));
		EXTRACT_STRING(sub.contact, VAL_STRING(&values[contact_col]));
		EXTRACT_STRING(sub.record_route, VAL_STRING(&values[rroute_col]));
		EXTRACT_STRING(sub.event_id, VAL_STRING(&values[event_id_col]));
		EXTRACT_STRING(sub.reason, VAL_STRING(&values[reason_col]));
		EXTRACT_STRING(ev_sname, VAL_STRING(&values[event_col]));
		sub.event = pres_contains_event(&ev_sname, &parsed_event);
		if (sub.event == NULL)
		{
			LM_ERR("event not found and set to NULL\n");
			goto done;
		}

		sub.local_cseq = VAL_INT(&values[lcseq_col]);
		sub.remote_cseq = VAL_INT(&values[rcseq_col]);
		sub.status = VAL_INT(&values[status_col]);
		sub.version = VAL_INT(&values[version_col]);
		if (VAL_INT(&values[expires_col]) > now + rls_expires_offset)
		{
			sub.expires = VAL_INT(&values[expires_col]) - now;

			if (rls_get_service_list(&sub.pres_uri, &sub.watcher_user,
				&sub.watcher_domain, &service_node, &doc) < 0)
			{
				LM_ERR("failed getting resource list\n");
				goto done;
			}
			if (doc == NULL)
			{
				LM_WARN("no document returned for uri <%.*s>\n",
					sub.pres_uri.len, sub.pres_uri.s);
				goto done;
			}

			if (send_full_notify(&sub, service_node, &sub.pres_uri, 0) < 0)
			{
				LM_ERR("failed sending full state notify\n");
				goto done;
			}
			xmlFreeDoc(doc);
			doc = NULL;
		}
		else
		{
			sub.expires = 0;
			rls_send_notify(&sub, NULL, NULL, NULL);
			delete_rlsdb(&sub.callid, &sub.to_tag, &sub.from_tag);
		}
	}

done:
	if (result != NULL)
		rls_dbf.free_result(rls_db, result);
	if (doc != NULL)
		xmlFreeDoc(doc);
	if (dbmode == RLS_DB_ONLY && rls_dbf.abort_transaction)
	{
		if (rls_dbf.abort_transaction(rls_db) < 0)
			LM_ERR("in abort_transaction\n");
	}
}
Ejemplo n.º 4
0
static void timer_send_update_notifies(int round)
{
	db_key_t query_cols[1], update_cols[1], result_cols[6];
	db_val_t query_vals[1], update_vals[1];
	int did_col, resource_uri_col, auth_state_col, reason_col,
		pres_state_col, content_type_col;
	int n_result_cols= 0;
	db1_res_t *result= NULL;
	db_query_f query_fn = rlpres_dbf.query_lock ? rlpres_dbf.query_lock : rlpres_dbf.query;

	query_cols[0]= &str_updated_col;
	query_vals[0].type = DB1_INT;
	query_vals[0].nul = 0;
	query_vals[0].val.int_val= round;

	result_cols[did_col= n_result_cols++]= &str_rlsubs_did_col;
	result_cols[resource_uri_col= n_result_cols++]= &str_resource_uri_col;
	result_cols[auth_state_col= n_result_cols++]= &str_auth_state_col;
	result_cols[content_type_col= n_result_cols++]= &str_content_type_col;
	result_cols[reason_col= n_result_cols++]= &str_reason_col;
	result_cols[pres_state_col= n_result_cols++]= &str_presence_state_col;

	update_cols[0]= &str_updated_col;
	update_vals[0].type = DB1_INT;
	update_vals[0].nul = 0;
	update_vals[0].val.int_val= NO_UPDATE_TYPE; 

	/* query in alphabetical order after rlsusbs_did 
	 * (resource list Subscribe dialog indentifier)*/
	
	if (rlpres_dbf.use_table(rlpres_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto done;
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.start_transaction)
	{
		if (rlpres_dbf.start_transaction(rlpres_db, DB_LOCKING_WRITE) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto done;
		}
	}

	if(query_fn(rlpres_db, query_cols, 0, query_vals, result_cols,
					1, n_result_cols, &str_rlsubs_did_col, &result)< 0)
	{
		LM_ERR("in sql query\n");
		goto done;
	}
	if(result == NULL || result->n <= 0)
		goto done;

	if(rlpres_dbf.update(rlpres_db, query_cols, 0, query_vals, update_cols,
					update_vals, 1, 1)< 0)
	{
		LM_ERR("in sql update\n");
		goto done;
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.end_transaction)
	{
		if (rlpres_dbf.end_transaction(rlpres_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto done;
		}
	}

	send_notifies(result, did_col, resource_uri_col, auth_state_col, reason_col,
                  pres_state_col, content_type_col);
done:
	if(result)
		rlpres_dbf.free_result(rlpres_db, result);

	if (dbmode == RLS_DB_ONLY && rls_dbf.abort_transaction)
	{
		if (rlpres_dbf.abort_transaction(rlpres_db) < 0)
			LM_ERR("in abort_transaction\n");
	}
}