This patch makes the void pointer handle for lowcomms functionality per message and not per page allocation entry. A refcount handling for the handle was added to keep the message alive until the user doesn't need it anymore. There exists now a per message callback which will be called when allocating a new buffer. This callback will be guaranteed to be called according the order of the sending buffer, which can be used that the caller increments a sequence number for the dlm message handle. For transition process we cast the dlm_mhandle to dlm_msg and vice versa until the midcomms layer will implement a specific dlm_mhandle structure. Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
136 lines
3.4 KiB
C
136 lines
3.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/******************************************************************************
|
|
*******************************************************************************
|
|
**
|
|
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
|
** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
|
|
**
|
|
**
|
|
*******************************************************************************
|
|
******************************************************************************/
|
|
|
|
/*
|
|
* midcomms.c
|
|
*
|
|
* This is the appallingly named "mid-level" comms layer.
|
|
*
|
|
* Its purpose is to take packets from the "real" comms layer,
|
|
* split them up into packets and pass them to the interested
|
|
* part of the locking mechanism.
|
|
*
|
|
* It also takes messages from the locking layer, formats them
|
|
* into packets and sends them to the comms layer.
|
|
*/
|
|
|
|
#include "dlm_internal.h"
|
|
#include "lowcomms.h"
|
|
#include "config.h"
|
|
#include "lock.h"
|
|
#include "midcomms.h"
|
|
|
|
struct dlm_mhandle *dlm_midcomms_get_mhandle(int nodeid, int len,
|
|
gfp_t allocation, char **ppc)
|
|
{
|
|
return (struct dlm_mhandle *)dlm_lowcomms_new_msg(nodeid, len,
|
|
allocation, ppc,
|
|
NULL, NULL);
|
|
}
|
|
|
|
void dlm_midcomms_commit_mhandle(struct dlm_mhandle *mh)
|
|
{
|
|
dlm_lowcomms_commit_msg((struct dlm_msg *)mh);
|
|
dlm_lowcomms_put_msg((struct dlm_msg *)mh);
|
|
}
|
|
|
|
void dlm_midcomms_add_member(int nodeid) { }
|
|
|
|
void dlm_midcomms_remove_member(int nodeid) { }
|
|
|
|
int dlm_midcomms_start(void)
|
|
{
|
|
return dlm_lowcomms_start();
|
|
}
|
|
|
|
void dlm_midcomms_shutdown(void)
|
|
{
|
|
dlm_lowcomms_shutdown();
|
|
}
|
|
|
|
int dlm_midcomms_close(int nodeid)
|
|
{
|
|
return dlm_lowcomms_close(nodeid);
|
|
}
|
|
|
|
/*
|
|
* Called from the low-level comms layer to process a buffer of
|
|
* commands.
|
|
*/
|
|
|
|
int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
|
|
{
|
|
const unsigned char *ptr = buf;
|
|
const struct dlm_header *hd;
|
|
uint16_t msglen;
|
|
int ret = 0;
|
|
|
|
while (len >= sizeof(struct dlm_header)) {
|
|
hd = (struct dlm_header *)ptr;
|
|
|
|
/* no message should be more than DEFAULT_BUFFER_SIZE or
|
|
* less than dlm_header size.
|
|
*
|
|
* Some messages does not have a 8 byte length boundary yet
|
|
* which can occur in a unaligned memory access of some dlm
|
|
* messages. However this problem need to be fixed at the
|
|
* sending side, for now it seems nobody run into architecture
|
|
* related issues yet but it slows down some processing.
|
|
* Fixing this issue should be scheduled in future by doing
|
|
* the next major version bump.
|
|
*/
|
|
msglen = le16_to_cpu(hd->h_length);
|
|
if (msglen > DEFAULT_BUFFER_SIZE ||
|
|
msglen < sizeof(struct dlm_header)) {
|
|
log_print("received invalid length header: %u from node %d, will abort message parsing",
|
|
msglen, nodeid);
|
|
return -EBADMSG;
|
|
}
|
|
|
|
/* caller will take care that leftover
|
|
* will be parsed next call with more data
|
|
*/
|
|
if (msglen > len)
|
|
break;
|
|
|
|
switch (hd->h_cmd) {
|
|
case DLM_MSG:
|
|
if (msglen < sizeof(struct dlm_message)) {
|
|
log_print("dlm msg too small: %u, will skip this message",
|
|
msglen);
|
|
goto skip;
|
|
}
|
|
|
|
break;
|
|
case DLM_RCOM:
|
|
if (msglen < sizeof(struct dlm_rcom)) {
|
|
log_print("dlm rcom msg too small: %u, will skip this message",
|
|
msglen);
|
|
goto skip;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
log_print("unsupported h_cmd received: %u, will skip this message",
|
|
hd->h_cmd);
|
|
goto skip;
|
|
}
|
|
|
|
dlm_receive_buffer((union dlm_packet *)ptr, nodeid);
|
|
|
|
skip:
|
|
ret += msglen;
|
|
len -= msglen;
|
|
ptr += msglen;
|
|
}
|
|
|
|
return ret;
|
|
}
|