1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/fs/dlm/midcomms.c
Alexander Aring 8f2dc78dbc fs: dlm: make buffer handling per msg
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>
2021-05-25 09:22:20 -05:00

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;
}