From 1c21ea3fa43fca0c486e12eb9d0b0b371f1ad7fd Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 29 Aug 2024 17:34:43 +0900 Subject: [PATCH] ksmbd: add refcnt to ksmbd_conn struct Signed-off-by: Namjae Jeon --- connection.c | 4 +++- connection.h | 1 + oplock.c | 28 +++++++++------------------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/connection.c b/connection.c index d0554836..c32fb46d 100644 --- a/connection.c +++ b/connection.c @@ -42,7 +42,8 @@ void ksmbd_conn_free(struct ksmbd_conn *conn) xa_destroy(&conn->sessions); kvfree(conn->request_buf); kfree(conn->preauth_info); - kfree(conn); + if (atomic_dec_and_test(&conn->refcnt)) + kfree(conn); } /** @@ -75,6 +76,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) conn->um = NULL; atomic_set(&conn->req_running, 0); atomic_set(&conn->r_count, 0); + atomic_set(&conn->refcnt, 1); conn->total_credits = 1; conn->outstanding_credits = 0; diff --git a/connection.h b/connection.h index 5b947175..b379ae4f 100644 --- a/connection.h +++ b/connection.h @@ -106,6 +106,7 @@ struct ksmbd_conn { bool signing_negotiated; __le16 signing_algorithm; bool binding; + atomic_t refcnt; }; struct ksmbd_conn_ops { diff --git a/oplock.c b/oplock.c index 10e16e2a..ff5fa92c 100644 --- a/oplock.c +++ b/oplock.c @@ -57,6 +57,7 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, init_waitqueue_head(&opinfo->oplock_brk); atomic_set(&opinfo->refcount, 1); atomic_set(&opinfo->breaking_cnt, 0); + atomic_inc(&opinfo->conn->refcnt); return opinfo; } @@ -130,6 +131,8 @@ static void free_opinfo(struct oplock_info *opinfo) { if (opinfo->is_lease) free_lease(opinfo); + if (atomic_dec_and_test(&opinfo->conn->refcnt)) + kfree(opinfo->conn); kfree(opinfo); } @@ -155,8 +158,7 @@ static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci) opinfo = list_first_entry(&ci->m_op_list, struct oplock_info, op_entry); if (opinfo) { - if (opinfo->conn == NULL || - !atomic_inc_not_zero(&opinfo->refcount)) + if (!atomic_inc_not_zero(&opinfo->refcount)) opinfo = NULL; else { atomic_inc(&opinfo->conn->r_count); @@ -1320,7 +1322,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, down_read(&p_ci->m_lock); list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { - if (opinfo->conn == NULL || !opinfo->is_lease) + if (!opinfo->is_lease) continue; if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE && @@ -1330,11 +1332,8 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, if (!atomic_inc_not_zero(&opinfo->refcount)) continue; - atomic_inc(&opinfo->conn->r_count); - if (ksmbd_conn_releasing(opinfo->conn)) { - atomic_dec(&opinfo->conn->r_count); + if (ksmbd_conn_releasing(opinfo->conn)) continue; - } oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE); opinfo_conn_put(opinfo); @@ -1361,18 +1360,15 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp) down_read(&p_ci->m_lock); list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { - if (opinfo->conn == NULL || !opinfo->is_lease) + if (!opinfo->is_lease) continue; if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE) { if (!atomic_inc_not_zero(&opinfo->refcount)) continue; - atomic_inc(&opinfo->conn->r_count); - if (ksmbd_conn_releasing(opinfo->conn)) { - atomic_dec(&opinfo->conn->r_count); + if (ksmbd_conn_releasing(opinfo->conn)) continue; - } oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE); opinfo_conn_put(opinfo); } @@ -1571,17 +1567,11 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp, down_read(&ci->m_lock); list_for_each_entry(brk_op, &ci->m_op_list, op_entry) { - if (brk_op->conn == NULL) - continue; - if (!atomic_inc_not_zero(&brk_op->refcount)) continue; - atomic_inc(&brk_op->conn->r_count); - if (ksmbd_conn_releasing(brk_op->conn)) { - atomic_dec(&brk_op->conn->r_count); + if (ksmbd_conn_releasing(brk_op->conn)) continue; - } #ifdef CONFIG_SMB_INSECURE_SERVER if (brk_op->is_smb2) {