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

Commit a41a8bae authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 5e61b64d b6d8773c
Loading
Loading
Loading
Loading
+39 −25
Original line number Original line 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),
	diagpriv_data = kmalloc(sizeof(struct diagchar_priv),
							GFP_KERNEL);
							GFP_KERNEL);
	if (diagpriv_data)
	if (!diagpriv_data)
		return -ENOMEM;
	driver->client_map[i].pid = current->tgid;
	diagpriv_data->pid = current->tgid;
	diagpriv_data->pid = current->tgid;
	file->private_data = diagpriv_data;
	file->private_data = diagpriv_data;
	strlcpy(driver->client_map[i].name, current->comm, 20);
	strlcpy(driver->client_map[i].name, current->comm, 20);
	driver->client_map[i].name[19] = '\0';
	driver->client_map[i].name[19] = '\0';
	return 0;
}
}


static void diag_mempool_init(void)
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)
static int diagchar_open(struct inode *inode, struct file *file)
{
{
	int i = 0;
	int i = 0, ret = 0;
	void *temp;
	void *temp;


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


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


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


	diagpriv_data = file->private_data;
	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
	 * clean up any DCI registrations, if this is a DCI client
	 * This will specially help in case of ungraceful exit of any 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);
	mutex_lock(&driver->dci_mutex);
	do {
	do {
		dci_entry = dci_lookup_client_entry_pid(current->tgid);
		dci_entry = dci_lookup_client_entry_pid(diagpriv_data->pid);
		if (dci_entry)
		if (dci_entry)
			diag_dci_deinit_client(dci_entry);
			diag_dci_deinit_client(dci_entry);
	} while (dci_entry);
	} while (dci_entry);
	mutex_unlock(&driver->dci_mutex);
	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 */
	/* 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);
	mutex_lock(&driver->diagchar_mutex);
	driver->ref_count--;
	driver->ref_count--;
	if (driver->ref_count == 0)
	if (driver->ref_count == 0)
		diag_mempool_exit();
		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;
	driver->client_map[i].pid = 0;
	kfree(diagpriv_data);
	kfree(diagpriv_data);
	diagpriv_data = NULL;
	diagpriv_data = NULL;
			file->private_data = 0;
	file->private_data = NULL;
			break;

		}
	}
	mutex_unlock(&driver->diagchar_mutex);
	mutex_unlock(&driver->diagchar_mutex);
	mutex_unlock(&driver->diag_file_mutex);
	mutex_unlock(&driver->diag_file_mutex);
	return 0;
	return 0;
@@ -602,8 +618,6 @@ static int diagchar_close(struct inode *inode, struct file *file)
{
{
	int ret;
	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);
	ret = diag_remove_client_entry(file);


	return ret;
	return ret;