Bluetooth: MGMT: Fix holding hci_conn reference while command is queued

This removes the use of hci_conn_hold from Get Conn Info and Get Clock
Info since the callback can just do a lookup by address using the cmd
data and only then set cmd->user_data to pass to the complete callback.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2022-07-21 15:56:28 -07:00
parent 1f7435c8f6
commit 7b445e220d
1 changed files with 12 additions and 39 deletions

View File

@ -6711,11 +6711,6 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
&rp, sizeof(rp));
if (conn) {
hci_conn_drop(conn);
hci_conn_put(conn);
}
mgmt_pending_free(cmd);
}
@ -6734,15 +6729,10 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
else
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
if (!conn || conn != cmd->user_data || conn->state != BT_CONNECTED) {
if (cmd->user_data) {
hci_conn_drop(cmd->user_data);
hci_conn_put(cmd->user_data);
cmd->user_data = NULL;
}
if (!conn || conn->state != BT_CONNECTED)
return MGMT_STATUS_NOT_CONNECTED;
}
cmd->user_data = conn;
handle = cpu_to_le16(conn->handle);
/* Refresh RSSI each time */
@ -6824,8 +6814,6 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
if (!cmd) {
err = -ENOMEM;
} else {
hci_conn_hold(conn);
cmd->user_data = hci_conn_get(conn);
err = hci_cmd_sync_queue(hdev, get_conn_info_sync,
cmd, get_conn_info_complete);
}
@ -6878,8 +6866,6 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
if (conn) {
rp.piconet_clock = cpu_to_le32(conn->clock);
rp.accuracy = cpu_to_le16(conn->clock_accuracy);
hci_conn_drop(conn);
hci_conn_put(conn);
}
complete:
@ -6894,30 +6880,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
struct mgmt_pending_cmd *cmd = data;
struct mgmt_cp_get_clock_info *cp = cmd->param;
struct hci_cp_read_clock hci_cp;
struct hci_conn *conn = cmd->user_data;
int err;
struct hci_conn *conn;
memset(&hci_cp, 0, sizeof(hci_cp));
err = hci_read_clock_sync(hdev, &hci_cp);
hci_read_clock_sync(hdev, &hci_cp);
if (conn) {
/* Make sure connection still exists */
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
&cp->addr.bdaddr);
/* Make sure connection still exists */
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
if (!conn || conn->state != BT_CONNECTED)
return MGMT_STATUS_NOT_CONNECTED;
if (conn && conn == cmd->user_data &&
conn->state == BT_CONNECTED) {
hci_cp.handle = cpu_to_le16(conn->handle);
hci_cp.which = 0x01; /* Piconet clock */
err = hci_read_clock_sync(hdev, &hci_cp);
} else if (cmd->user_data) {
hci_conn_drop(cmd->user_data);
hci_conn_put(cmd->user_data);
cmd->user_data = NULL;
}
}
cmd->user_data = conn;
hci_cp.handle = cpu_to_le16(conn->handle);
hci_cp.which = 0x01; /* Piconet clock */
return err;
return hci_read_clock_sync(hdev, &hci_cp);
}
static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
@ -6976,10 +6953,6 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
if (cmd)
mgmt_pending_free(cmd);
} else if (conn) {
hci_conn_hold(conn);
cmd->user_data = hci_conn_get(conn);
}