Unverified Commit e7f7d85f authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3128 fix ksmbd to release the ones allocated for async work

Merge Pull Request from: @ci-robot 
 
PR sync from: Zizhi Wo <wozizhi@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/PZ7Y3LKHTEA6K5IVNX7VTII65M4EHBNL/ 
Fix memory leak and typo. What's more, add release_async_work() to delete
asynchronous work.

Dawei Li (1):
  ksmbd: fix typo, syncronous->synchronous

Hangyu Hua (1):
  ksmbd: fix possible memory leak in smb2_lock()

Jakob Koschel (1):
  ksmbd: replace usage of found with dedicated list iterator variable

Namjae Jeon (1):
  ksmbd: delete asynchronous work from list


-- 
2.39.2
 
https://gitee.com/src-openeuler/kernel/issues/I6KEWO?from=project-issue 
 
Link:https://gitee.com/openeuler/kernel/pulls/3128

 

Reviewed-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents eff35174 ca837b4e
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -106,10 +106,8 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work)
	struct ksmbd_conn *conn = work->conn;
	struct list_head *requests_queue = NULL;

	if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) {
	if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE)
		requests_queue = &conn->requests;
		work->syncronous = true;
	}

	if (requests_queue) {
		atomic_inc(&conn->req_running);
@@ -130,14 +128,14 @@ int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)

	if (!work->multiRsp)
		atomic_dec(&conn->req_running);
	spin_lock(&conn->request_lock);
	if (!work->multiRsp) {
		spin_lock(&conn->request_lock);
		list_del_init(&work->request_entry);
		if (work->syncronous == false)
			list_del_init(&work->async_request_entry);
		spin_unlock(&conn->request_lock);
		if (work->asynchronous)
			release_async_work(work);
		ret = 0;
	}
	spin_unlock(&conn->request_lock);

	wake_up_all(&conn->req_running_q);
	return ret;
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ struct ksmbd_work {
	/* Request is encrypted */
	bool                            encrypted:1;
	/* Is this SYNC or ASYNC ksmbd_work */
	bool                            syncronous:1;
	bool                            asynchronous:1;
	bool                            need_invalidate_rkey:1;

	unsigned int                    remote_key;
+36 −30
Original line number Diff line number Diff line
@@ -519,12 +519,6 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work)
	rsp_hdr->SessionId = rcv_hdr->SessionId;
	memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);

	work->syncronous = true;
	if (work->async_id) {
		ksmbd_release_id(&conn->async_ida, work->async_id);
		work->async_id = 0;
	}

	return 0;
}

@@ -682,7 +676,7 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
		pr_err("Failed to alloc async message id\n");
		return id;
	}
	work->syncronous = false;
	work->asynchronous = true;
	work->async_id = id;
	rsp_hdr->Id.AsyncId = cpu_to_le64(id);

@@ -702,6 +696,24 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
	return 0;
}

void release_async_work(struct ksmbd_work *work)
{
	struct ksmbd_conn *conn = work->conn;

	spin_lock(&conn->request_lock);
	list_del_init(&work->async_request_entry);
	spin_unlock(&conn->request_lock);

	work->asynchronous = 0;
	work->cancel_fn = NULL;
	kfree(work->cancel_argv);
	work->cancel_argv = NULL;
	if (work->async_id) {
		ksmbd_release_id(&conn->async_ida, work->async_id);
		work->async_id = 0;
	}
}

void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
{
	struct smb2_hdr *rsp_hdr;
@@ -6655,8 +6667,7 @@ int smb2_cancel(struct ksmbd_work *work)
	struct ksmbd_conn *conn = work->conn;
	struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
	struct smb2_hdr *chdr;
	struct ksmbd_work *cancel_work = NULL;
	int canceled = 0;
	struct ksmbd_work *iter;
	struct list_head *command_list;

	ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
@@ -6666,11 +6677,11 @@ int smb2_cancel(struct ksmbd_work *work)
		command_list = &conn->async_requests;

		spin_lock(&conn->request_lock);
		list_for_each_entry(cancel_work, command_list,
		list_for_each_entry(iter, command_list,
				    async_request_entry) {
			chdr = smb2_get_msg(cancel_work->request_buf);
			chdr = smb2_get_msg(iter->request_buf);

			if (cancel_work->async_id !=
			if (iter->async_id !=
			    le64_to_cpu(hdr->Id.AsyncId))
				continue;

@@ -6678,7 +6689,9 @@ int smb2_cancel(struct ksmbd_work *work)
				    "smb2 with AsyncId %llu cancelled command = 0x%x\n",
				    le64_to_cpu(hdr->Id.AsyncId),
				    le16_to_cpu(chdr->Command));
			canceled = 1;
			iter->state = KSMBD_WORK_CANCELLED;
			if (iter->cancel_fn)
				iter->cancel_fn(iter->cancel_argv);
			break;
		}
		spin_unlock(&conn->request_lock);
@@ -6686,29 +6699,23 @@ int smb2_cancel(struct ksmbd_work *work)
		command_list = &conn->requests;

		spin_lock(&conn->request_lock);
		list_for_each_entry(cancel_work, command_list, request_entry) {
			chdr = smb2_get_msg(cancel_work->request_buf);
		list_for_each_entry(iter, command_list, request_entry) {
			chdr = smb2_get_msg(iter->request_buf);

			if (chdr->MessageId != hdr->MessageId ||
			    cancel_work == work)
			    iter == work)
				continue;

			ksmbd_debug(SMB,
				    "smb2 with mid %llu cancelled command = 0x%x\n",
				    le64_to_cpu(hdr->MessageId),
				    le16_to_cpu(chdr->Command));
			canceled = 1;
			iter->state = KSMBD_WORK_CANCELLED;
			break;
		}
		spin_unlock(&conn->request_lock);
	}

	if (canceled) {
		cancel_work->state = KSMBD_WORK_CANCELLED;
		if (cancel_work->cancel_fn)
			cancel_work->cancel_fn(cancel_work->cancel_argv);
	}

	/* For SMB2_CANCEL command itself send no response*/
	work->send_no_response = 1;
	return 0;
@@ -7072,6 +7079,10 @@ int smb2_lock(struct ksmbd_work *work)

				ksmbd_vfs_posix_lock_wait(flock);

				spin_lock(&fp->f_lock);
				list_del(&work->fp_entry);
				spin_unlock(&fp->f_lock);

				if (work->state != KSMBD_WORK_ACTIVE) {
					list_del(&smb_lock->llist);
					spin_lock(&work->conn->llist_lock);
@@ -7080,9 +7091,6 @@ int smb2_lock(struct ksmbd_work *work)
					locks_free_lock(flock);

					if (work->state == KSMBD_WORK_CANCELLED) {
						spin_lock(&fp->f_lock);
						list_del(&work->fp_entry);
						spin_unlock(&fp->f_lock);
						rsp->hdr.Status =
							STATUS_CANCELLED;
						kfree(smb_lock);
@@ -7091,6 +7099,7 @@ int smb2_lock(struct ksmbd_work *work)
						work->send_no_response = 1;
						goto out;
					}

					init_smb2_rsp_hdr(work);
					smb2_set_err_rsp(work);
					rsp->hdr.Status =
@@ -7103,10 +7112,7 @@ int smb2_lock(struct ksmbd_work *work)
				spin_lock(&work->conn->llist_lock);
				list_del(&smb_lock->clist);
				spin_unlock(&work->conn->llist_lock);

				spin_lock(&fp->f_lock);
				list_del(&work->fp_entry);
				spin_unlock(&fp->f_lock);
				release_async_work(work);
				goto retry;
			} else if (!rc) {
				spin_lock(&work->conn->llist_lock);
+1 −0
Original line number Diff line number Diff line
@@ -1664,6 +1664,7 @@ int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects,
struct file_lock *smb_flock_init(struct file *f);
int setup_async_work(struct ksmbd_work *work, void (*fn)(void **),
		     void **arg);
void release_async_work(struct ksmbd_work *work);
void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
struct channel *lookup_chann_list(struct ksmbd_session *sess,
				  struct ksmbd_conn *conn);
+2 −3
Original line number Diff line number Diff line
@@ -364,12 +364,11 @@ static void __put_fd_final(struct ksmbd_work *work, struct ksmbd_file *fp)

static void set_close_state_blocked_works(struct ksmbd_file *fp)
{
	struct ksmbd_work *cancel_work, *ctmp;
	struct ksmbd_work *cancel_work;

	spin_lock(&fp->f_lock);
	list_for_each_entry_safe(cancel_work, ctmp, &fp->blocked_works,
	list_for_each_entry(cancel_work, &fp->blocked_works,
				 fp_entry) {
		list_del(&cancel_work->fp_entry);
		cancel_work->state = KSMBD_WORK_CLOSED;
		cancel_work->cancel_fn(cancel_work->cancel_argv);
	}