Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+12 -39
+12 -39
net/bluetooth/mgmt.c
··· 6711 6711 mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, 6712 6712 &rp, sizeof(rp)); 6713 6713 6714 - if (conn) { 6715 - hci_conn_drop(conn); 6716 - hci_conn_put(conn); 6717 - } 6718 - 6719 6714 mgmt_pending_free(cmd); 6720 6715 } 6721 6716 ··· 6729 6734 else 6730 6735 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); 6731 6736 6732 - if (!conn || conn != cmd->user_data || conn->state != BT_CONNECTED) { 6733 - if (cmd->user_data) { 6734 - hci_conn_drop(cmd->user_data); 6735 - hci_conn_put(cmd->user_data); 6736 - cmd->user_data = NULL; 6737 - } 6737 + if (!conn || conn->state != BT_CONNECTED) 6738 6738 return MGMT_STATUS_NOT_CONNECTED; 6739 - } 6740 6739 6740 + cmd->user_data = conn; 6741 6741 handle = cpu_to_le16(conn->handle); 6742 6742 6743 6743 /* Refresh RSSI each time */ ··· 6814 6824 if (!cmd) { 6815 6825 err = -ENOMEM; 6816 6826 } else { 6817 - hci_conn_hold(conn); 6818 - cmd->user_data = hci_conn_get(conn); 6819 6827 err = hci_cmd_sync_queue(hdev, get_conn_info_sync, 6820 6828 cmd, get_conn_info_complete); 6821 6829 } ··· 6866 6878 if (conn) { 6867 6879 rp.piconet_clock = cpu_to_le32(conn->clock); 6868 6880 rp.accuracy = cpu_to_le16(conn->clock_accuracy); 6869 - hci_conn_drop(conn); 6870 - hci_conn_put(conn); 6871 6881 } 6872 6882 6873 6883 complete: ··· 6880 6894 struct mgmt_pending_cmd *cmd = data; 6881 6895 struct mgmt_cp_get_clock_info *cp = cmd->param; 6882 6896 struct hci_cp_read_clock hci_cp; 6883 - struct hci_conn *conn = cmd->user_data; 6884 - int err; 6897 + struct hci_conn *conn; 6885 6898 6886 6899 memset(&hci_cp, 0, sizeof(hci_cp)); 6887 - err = hci_read_clock_sync(hdev, &hci_cp); 6900 + hci_read_clock_sync(hdev, &hci_cp); 6888 6901 6889 - if (conn) { 6890 - /* Make sure connection still exists */ 6891 - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, 6892 - &cp->addr.bdaddr); 6902 + /* Make sure connection still exists */ 6903 + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); 6904 + if (!conn || conn->state != BT_CONNECTED) 6905 + return MGMT_STATUS_NOT_CONNECTED; 6893 6906 6894 - if (conn && conn == cmd->user_data && 6895 - conn->state == BT_CONNECTED) { 6896 - hci_cp.handle = cpu_to_le16(conn->handle); 6897 - hci_cp.which = 0x01; /* Piconet clock */ 6898 - err = hci_read_clock_sync(hdev, &hci_cp); 6899 - } else if (cmd->user_data) { 6900 - hci_conn_drop(cmd->user_data); 6901 - hci_conn_put(cmd->user_data); 6902 - cmd->user_data = NULL; 6903 - } 6904 - } 6907 + cmd->user_data = conn; 6908 + hci_cp.handle = cpu_to_le16(conn->handle); 6909 + hci_cp.which = 0x01; /* Piconet clock */ 6905 6910 6906 - return err; 6911 + return hci_read_clock_sync(hdev, &hci_cp); 6907 6912 } 6908 6913 6909 6914 static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, ··· 6953 6976 6954 6977 if (cmd) 6955 6978 mgmt_pending_free(cmd); 6956 - 6957 - } else if (conn) { 6958 - hci_conn_hold(conn); 6959 - cmd->user_data = hci_conn_get(conn); 6960 6979 } 6961 6980 6962 6981