Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6d8773c authored by Hardik Arya's avatar Hardik Arya
Browse files

diag: Use file's private data to get pid of exiting process



Close to diag fd can be called from a work function having
different pid from process who has registered with diag.
This is resulting in not removing cmd registration for exiting
process. The patch fixes this issue with using file's private
data to get pid of exiting process.

Change-Id: I1036b9e159b1668558da62fe7588acf1367d6aeb
Signed-off-by: default avatarHardik Arya <harya@codeaurora.org>
parent 143e58dc
Loading
Loading
Loading
Loading
+39 −25
Original line number Diff line number Diff line
@@ -276,18 +276,20 @@ void check_drain_timer(void)
	}
}

void diag_add_client(int i, struct file *file)
static int diag_add_client(int i, struct file *file)
{
	struct diagchar_priv *diagpriv_data;
	struct diagchar_priv *diagpriv_data = NULL;

	driver->client_map[i].pid = current->tgid;
	diagpriv_data = kmalloc(sizeof(struct diagchar_priv),
							GFP_KERNEL);
	if (diagpriv_data)
	if (!diagpriv_data)
		return -ENOMEM;
	driver->client_map[i].pid = current->tgid;
	diagpriv_data->pid = current->tgid;
	file->private_data = diagpriv_data;
	strlcpy(driver->client_map[i].name, current->comm, 20);
	driver->client_map[i].name[19] = '\0';
	return 0;
}

static void diag_mempool_init(void)
@@ -323,7 +325,7 @@ static void diag_mempool_exit(void)

static int diagchar_open(struct inode *inode, struct file *file)
{
	int i = 0;
	int i = 0, ret = 0;
	void *temp;

	if (driver) {
@@ -334,7 +336,12 @@ static int diagchar_open(struct inode *inode, struct file *file)
				break;

		if (i < driver->num_clients) {
			diag_add_client(i, file);
			ret = diag_add_client(i, file);
			if (ret < 0) {
				mutex_unlock(&driver->diagchar_mutex);
				pr_err_ratelimited("diag: Insufficient memory for adding new client\n");
				return ret;
			}
		} else {
			if (i < THRESHOLD_CLIENT_LIMIT) {
				driver->num_clients++;
@@ -352,7 +359,9 @@ static int diagchar_open(struct inode *inode, struct file *file)
					goto fail;
				else
					driver->data_ready = temp;
				diag_add_client(i, file);
				ret = diag_add_client(i, file);
				if (ret < 0)
					goto fail;
			} else {
				mutex_unlock(&driver->diagchar_mutex);
				pr_err_ratelimited("diag: Max client limit for DIAG reached\n");
@@ -389,7 +398,7 @@ static int diagchar_open(struct inode *inode, struct file *file)
fail:
	driver->num_clients--;
	mutex_unlock(&driver->diagchar_mutex);
	pr_err_ratelimited("diag: Insufficient memory for new client");
	pr_err_ratelimited("diag: Insufficient memory for new client\n");
	return -ENOMEM;
}

@@ -560,7 +569,19 @@ static int diag_remove_client_entry(struct file *file)
	}

	diagpriv_data = file->private_data;

	for (i = 0; i < driver->num_clients; i++)
		if (diagpriv_data && diagpriv_data->pid ==
			driver->client_map[i].pid)
			break;
	if (i == driver->num_clients) {
		DIAG_LOG(DIAG_DEBUG_USERSPACE,
			"pid %d, not present in client map\n",
			diagpriv_data->pid);
		mutex_unlock(&driver->diag_file_mutex);
		return -EINVAL;
	}
	DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n",
		driver->client_map[i].name, diagpriv_data->pid);
	/*
	 * clean up any DCI registrations, if this is a DCI client
	 * This will specially help in case of ungraceful exit of any DCI client
@@ -568,32 +589,27 @@ static int diag_remove_client_entry(struct file *file)
	 */
	mutex_lock(&driver->dci_mutex);
	do {
		dci_entry = dci_lookup_client_entry_pid(current->tgid);
		dci_entry = dci_lookup_client_entry_pid(diagpriv_data->pid);
		if (dci_entry)
			diag_dci_deinit_client(dci_entry);
	} while (dci_entry);
	mutex_unlock(&driver->dci_mutex);

	diag_close_logging_process(current->tgid);
	diag_close_logging_process(diagpriv_data->pid);

	/* Delete the pkt response table entry for the exiting process */
	diag_cmd_remove_reg_by_pid(current->tgid);
	diag_cmd_remove_reg_by_pid(diagpriv_data->pid);

	mutex_lock(&driver->diagchar_mutex);
	driver->ref_count--;
	if (driver->ref_count == 0)
		diag_mempool_exit();

	for (i = 0; i < driver->num_clients; i++) {
		if (diagpriv_data && diagpriv_data->pid ==
						driver->client_map[i].pid) {
	driver->client_map[i].pid = 0;
	kfree(diagpriv_data);
	diagpriv_data = NULL;
			file->private_data = 0;
			break;
		}
	}
	file->private_data = NULL;

	mutex_unlock(&driver->diagchar_mutex);
	mutex_unlock(&driver->diag_file_mutex);
	return 0;
@@ -602,8 +618,6 @@ static int diagchar_close(struct inode *inode, struct file *file)
{
	int ret;

	DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n",
		current->comm, current->tgid);
	ret = diag_remove_client_entry(file);

	return ret;