Skip to content

Commit 3a9b557

Browse files
namjaejeonsmfrench
authored andcommitted
ksmbd: delete asynchronous work from list
When smb2_lock request is canceled by smb2_cancel or smb2_close(), ksmbd is missing deleting async_request_entry async_requests list. Because calling init_smb2_rsp_hdr() in smb2_lock() mark ->synchronous as true and then it will not be deleted in ksmbd_conn_try_dequeue_request(). This patch add release_async_work() to release the ones allocated for async work. Cc: [email protected] Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 2824861 commit 3a9b557

File tree

4 files changed

+28
-20
lines changed

4 files changed

+28
-20
lines changed

fs/ksmbd/connection.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,8 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work)
112112
struct ksmbd_conn *conn = work->conn;
113113
struct list_head *requests_queue = NULL;
114114

115-
if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) {
115+
if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE)
116116
requests_queue = &conn->requests;
117-
work->synchronous = true;
118-
}
119117

120118
if (requests_queue) {
121119
atomic_inc(&conn->req_running);
@@ -136,14 +134,14 @@ int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
136134

137135
if (!work->multiRsp)
138136
atomic_dec(&conn->req_running);
139-
spin_lock(&conn->request_lock);
140137
if (!work->multiRsp) {
138+
spin_lock(&conn->request_lock);
141139
list_del_init(&work->request_entry);
142-
if (!work->synchronous)
143-
list_del_init(&work->async_request_entry);
140+
spin_unlock(&conn->request_lock);
141+
if (work->asynchronous)
142+
release_async_work(work);
144143
ret = 0;
145144
}
146-
spin_unlock(&conn->request_lock);
147145

148146
wake_up_all(&conn->req_running_q);
149147
return ret;

fs/ksmbd/ksmbd_work.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct ksmbd_work {
6868
/* Request is encrypted */
6969
bool encrypted:1;
7070
/* Is this SYNC or ASYNC ksmbd_work */
71-
bool synchronous:1;
71+
bool asynchronous:1;
7272
bool need_invalidate_rkey:1;
7373

7474
unsigned int remote_key;

fs/ksmbd/smb2pdu.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -498,12 +498,6 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work)
498498
rsp_hdr->SessionId = rcv_hdr->SessionId;
499499
memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16);
500500

501-
work->synchronous = true;
502-
if (work->async_id) {
503-
ksmbd_release_id(&conn->async_ida, work->async_id);
504-
work->async_id = 0;
505-
}
506-
507501
return 0;
508502
}
509503

@@ -644,7 +638,7 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
644638
pr_err("Failed to alloc async message id\n");
645639
return id;
646640
}
647-
work->synchronous = false;
641+
work->asynchronous = true;
648642
work->async_id = id;
649643
rsp_hdr->Id.AsyncId = cpu_to_le64(id);
650644

@@ -664,6 +658,24 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
664658
return 0;
665659
}
666660

661+
void release_async_work(struct ksmbd_work *work)
662+
{
663+
struct ksmbd_conn *conn = work->conn;
664+
665+
spin_lock(&conn->request_lock);
666+
list_del_init(&work->async_request_entry);
667+
spin_unlock(&conn->request_lock);
668+
669+
work->asynchronous = 0;
670+
work->cancel_fn = NULL;
671+
kfree(work->cancel_argv);
672+
work->cancel_argv = NULL;
673+
if (work->async_id) {
674+
ksmbd_release_id(&conn->async_ida, work->async_id);
675+
work->async_id = 0;
676+
}
677+
}
678+
667679
void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
668680
{
669681
struct smb2_hdr *rsp_hdr;
@@ -7045,13 +7057,9 @@ int smb2_lock(struct ksmbd_work *work)
70457057

70467058
ksmbd_vfs_posix_lock_wait(flock);
70477059

7048-
spin_lock(&work->conn->request_lock);
70497060
spin_lock(&fp->f_lock);
70507061
list_del(&work->fp_entry);
7051-
work->cancel_fn = NULL;
7052-
kfree(argv);
70537062
spin_unlock(&fp->f_lock);
7054-
spin_unlock(&work->conn->request_lock);
70557063

70567064
if (work->state != KSMBD_WORK_ACTIVE) {
70577065
list_del(&smb_lock->llist);
@@ -7069,6 +7077,7 @@ int smb2_lock(struct ksmbd_work *work)
70697077
work->send_no_response = 1;
70707078
goto out;
70717079
}
7080+
70727081
init_smb2_rsp_hdr(work);
70737082
smb2_set_err_rsp(work);
70747083
rsp->hdr.Status =
@@ -7081,7 +7090,7 @@ int smb2_lock(struct ksmbd_work *work)
70817090
spin_lock(&work->conn->llist_lock);
70827091
list_del(&smb_lock->clist);
70837092
spin_unlock(&work->conn->llist_lock);
7084-
7093+
release_async_work(work);
70857094
goto retry;
70867095
} else if (!rc) {
70877096
spin_lock(&work->conn->llist_lock);

fs/ksmbd/smb2pdu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects,
486486
struct file_lock *smb_flock_init(struct file *f);
487487
int setup_async_work(struct ksmbd_work *work, void (*fn)(void **),
488488
void **arg);
489+
void release_async_work(struct ksmbd_work *work);
489490
void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
490491
struct channel *lookup_chann_list(struct ksmbd_session *sess,
491492
struct ksmbd_conn *conn);

0 commit comments

Comments
 (0)