/* 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); }
/* 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; }
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"); } }
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"); } }