/** * ksmbd_conn_free() - free resources of the connection instance * * @conn: connection instance to be cleaned up * * During the thread termination, the corresponding conn instance * resources(sock/memory) are released and finally the conn object is freed.
*/ void ksmbd_conn_free(struct ksmbd_conn *conn)
{
down_write(&conn_list_lock);
list_del(&conn->conns_list);
up_write(&conn_list_lock);
xa_destroy(&conn->sessions);
kvfree(conn->request_buf);
kfree(conn->preauth_info); if (atomic_dec_and_test(&conn->refcnt)) {
conn->transport->ops->free_transport(conn->transport);
kfree(conn);
}
}
/** * ksmbd_conn_alloc() - initialize a new connection instance * * Return: ksmbd_conn struct on success, otherwise NULL
*/ struct ksmbd_conn *ksmbd_conn_alloc(void)
{ struct ksmbd_conn *conn;
conn = kzalloc(sizeof(struct ksmbd_conn), KSMBD_DEFAULT_GFP); if (!conn) return NULL;
if (sent < 0) {
pr_err("Failed to send message: %d\n", sent); return sent;
}
return 0;
}
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf, unsignedint buflen, struct smb2_buffer_desc_v1 *desc, unsignedint desc_len)
{ int ret = -EINVAL;
if (conn->transport->ops->rdma_read)
ret = conn->transport->ops->rdma_read(conn->transport,
buf, buflen,
desc, desc_len); return ret;
}
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf, unsignedint buflen, struct smb2_buffer_desc_v1 *desc, unsignedint desc_len)
{ int ret = -EINVAL;
if (conn->transport->ops->rdma_write)
ret = conn->transport->ops->rdma_write(conn->transport,
buf, buflen,
desc, desc_len); return ret;
}
bool ksmbd_conn_alive(struct ksmbd_conn *conn)
{ if (!ksmbd_server_running()) returnfalse;
if (ksmbd_conn_exiting(conn)) returnfalse;
if (kthread_should_stop()) returnfalse;
if (atomic_read(&conn->stats.open_files_count) > 0) returntrue;
/* * Stop current session if the time that get last request from client * is bigger than deadtime user configured and opening file count is * zero.
*/ if (server_conf.deadtime > 0 &&
time_after(jiffies, conn->last_active + server_conf.deadtime)) {
ksmbd_debug(CONN, "No response from client in %lu minutes\n",
server_conf.deadtime / SMB_ECHO_INTERVAL); returnfalse;
} returntrue;
}
if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==
SMB2_PROTO_NUMBER) { if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE) break;
}
if (!default_conn_ops.process_fn) {
pr_err("No connection request callback\n"); break;
}
if (default_conn_ops.process_fn(conn)) {
pr_err("Cannot handle request\n"); break;
}
}
out:
ksmbd_conn_set_releasing(conn); /* Wait till all reference dropped to the Server object*/
ksmbd_debug(CONN, "Wait for all pending requests(%d)\n", atomic_read(&conn->r_count));
wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);
if (IS_ENABLED(CONFIG_UNICODE))
utf8_unload(conn->um);
unload_nls(conn->local_nls); if (default_conn_ops.terminate_fn)
default_conn_ops.terminate_fn(conn);
t->ops->disconnect(t);
module_put(THIS_MODULE); return 0;
}
void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn)
{ /* * Checking waitqueue to dropping pending requests on * disconnection. waitqueue_active is safe because it * uses atomic operation for condition.
*/
atomic_inc(&conn->refcnt); if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
wake_up(&conn->r_count_q);
if (atomic_dec_and_test(&conn->refcnt))
kfree(conn);
}
int ksmbd_conn_transport_init(void)
{ int ret;
mutex_lock(&init_lock);
ret = ksmbd_tcp_init(); if (ret) {
pr_err("Failed to init TCP subsystem: %d\n", ret); goto out;
}
ret = ksmbd_rdma_init(); if (ret) {
pr_err("Failed to init RDMA subsystem: %d\n", ret); goto out;
}
out:
mutex_unlock(&init_lock); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.