linux/fs/ocfs2/cluster/tcp.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 * Copyright (C) 2004 Oracle.  All rights reserved.
 *
 * ----
 *
 * Callers for this were originally written against a very simple synchronus
 * API.  This implementation reflects those simple callers.  Some day I'm sure
 * we'll need to move to a more robust posting/callback mechanism.
 *
 * Transmit calls pass in kernel virtual addresses and block copying this into
 * the socket's tx buffers via a usual blocking sendmsg.  They'll block waiting
 * for a failed socket to timeout.  TX callers can also pass in a poniter to an
 * 'int' which gets filled with an errno off the wire in response to the
 * message they send.
 *
 * Handlers for unsolicited messages are registered.  Each socket has a page
 * that incoming data is copied into.  First the header, then the data.
 * Handlers are called from only one thread with a reference to this per-socket
 * page.  This page is destroyed after the handler call, so it can't be
 * referenced beyond the call.  Handlers may block but are discouraged from
 * doing so.
 *
 * Any framing errors (bad magic, large payload lengths) close a connection.
 *
 * Our sock_container holds the state we associate with a socket.  It's current
 * framing state is held there as well as the refcounting we do around when it
 * is safe to tear down the socket.  The socket is only finally torn down from
 * the container when the container loses all of its references -- so as long
 * as you hold a ref on the container you can trust that the socket is valid
 * for use with kernel socket APIs.
 *
 * Connections are initiated between a pair of nodes when the node with the
 * higher node number gets a heartbeat callback which indicates that the lower
 * numbered node has started heartbeating.  The lower numbered node is passive
 * and only accepts the connection if the higher numbered node is heartbeating.
 */

#include <linux/kernel.h>
#include <linux/sched/mm.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/kref.h>
#include <linux/net.h>
#include <linux/export.h>
#include <net/tcp.h>
#include <trace/events/sock.h>

#include <linux/uaccess.h>

#include "heartbeat.h"
#include "tcp.h"
#include "nodemanager.h"
#define MLOG_MASK_PREFIX
#include "masklog.h"
#include "quorum.h"

#include "tcp_internal.h"

#define SC_NODEF_FMT
#define SC_NODEF_ARGS(sc)

/*
 * In the following two log macros, the whitespace after the ',' just
 * before ##args is intentional. Otherwise, gcc 2.95 will eat the
 * previous token if args expands to nothing.
 */
#define msglog(hdr, fmt, args...)

#define sclog(sc, fmt, args...)

static DEFINE_RWLOCK(o2net_handler_lock);
static struct rb_root o2net_handler_tree =;

static struct o2net_node o2net_nodes[O2NM_MAX_NODES];

/* XXX someday we'll need better accounting */
static struct socket *o2net_listen_sock;

/*
 * listen work is only queued by the listening socket callbacks on the
 * o2net_wq.  teardown detaches the callbacks before destroying the workqueue.
 * quorum work is queued as sock containers are shutdown.. stop_listening
 * tears down all the node's sock containers, preventing future shutdowns
 * and queued quroum work, before canceling delayed quorum work and
 * destroying the work queue.
 */
static struct workqueue_struct *o2net_wq;
static struct work_struct o2net_listen_work;

static struct o2hb_callback_func o2net_hb_up, o2net_hb_down;
#define O2NET_HB_PRI

static struct o2net_handshake *o2net_hand;
static struct o2net_msg *o2net_keep_req, *o2net_keep_resp;

static int o2net_sys_err_translations[O2NET_ERR_MAX] =;

/* can't quite avoid *all* internal declarations :/ */
static void o2net_sc_connect_completed(struct work_struct *work);
static void o2net_rx_until_empty(struct work_struct *work);
static void o2net_shutdown_sc(struct work_struct *work);
static void o2net_listen_data_ready(struct sock *sk);
static void o2net_sc_send_keep_req(struct work_struct *work);
static void o2net_idle_timer(struct timer_list *t);
static void o2net_sc_postpone_idle(struct o2net_sock_container *sc);
static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc);

#ifdef CONFIG_DEBUG_FS
static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype,
			   u32 msgkey, struct task_struct *task, u8 node)
{}

static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst)
{}

static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst)
{}

static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst)
{}

static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst,
						struct o2net_sock_container *sc)
{}

static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst,
					u32 msg_id)
{}

static inline void o2net_set_sock_timer(struct o2net_sock_container *sc)
{}

static inline void o2net_set_data_ready_time(struct o2net_sock_container *sc)
{}

static inline void o2net_set_advance_start_time(struct o2net_sock_container *sc)
{}

static inline void o2net_set_advance_stop_time(struct o2net_sock_container *sc)
{}

static inline void o2net_set_func_start_time(struct o2net_sock_container *sc)
{}

static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc)
{}

#else  /* CONFIG_DEBUG_FS */
#define o2net_init_nst
#define o2net_set_nst_sock_time
#define o2net_set_nst_send_time
#define o2net_set_nst_status_time
#define o2net_set_nst_sock_container
#define o2net_set_nst_msg_id
#define o2net_set_sock_timer
#define o2net_set_data_ready_time
#define o2net_set_advance_start_time
#define o2net_set_advance_stop_time
#define o2net_set_func_start_time
#define o2net_set_func_stop_time
#endif /* CONFIG_DEBUG_FS */

#ifdef CONFIG_OCFS2_FS_STATS
static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc)
{}

static void o2net_update_send_stats(struct o2net_send_tracking *nst,
				    struct o2net_sock_container *sc)
{}

static void o2net_update_recv_stats(struct o2net_sock_container *sc)
{}

#else

#define o2net_update_send_stats

#define o2net_update_recv_stats

#endif /* CONFIG_OCFS2_FS_STATS */

static inline unsigned int o2net_reconnect_delay(void)
{}

static inline unsigned int o2net_keepalive_delay(void)
{}

static inline unsigned int o2net_idle_timeout(void)
{}

static inline int o2net_sys_err_to_errno(enum o2net_system_error err)
{}

static struct o2net_node * o2net_nn_from_num(u8 node_num)
{}

static u8 o2net_num_from_nn(struct o2net_node *nn)
{}

/* ------------------------------------------------------------ */

static int o2net_prep_nsw(struct o2net_node *nn, struct o2net_status_wait *nsw)
{}

static void o2net_complete_nsw_locked(struct o2net_node *nn,
				      struct o2net_status_wait *nsw,
				      enum o2net_system_error sys_status,
				      s32 status)
{}

static void o2net_complete_nsw(struct o2net_node *nn,
			       struct o2net_status_wait *nsw,
			       u64 id, enum o2net_system_error sys_status,
			       s32 status)
{}

static void o2net_complete_nodes_nsw(struct o2net_node *nn)
{}

static int o2net_nsw_completed(struct o2net_node *nn,
			       struct o2net_status_wait *nsw)
{}

/* ------------------------------------------------------------ */

static void sc_kref_release(struct kref *kref)
{}

static void sc_put(struct o2net_sock_container *sc)
{}
static void sc_get(struct o2net_sock_container *sc)
{}
static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
{}

/* ------------------------------------------------------------ */

static void o2net_sc_queue_work(struct o2net_sock_container *sc,
				struct work_struct *work)
{}
static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc,
					struct delayed_work *work,
					int delay)
{}
static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc,
					 struct delayed_work *work)
{}

static atomic_t o2net_connected_peers =;

int o2net_num_connected_peers(void)
{}

static void o2net_set_nn_state(struct o2net_node *nn,
			       struct o2net_sock_container *sc,
			       unsigned valid, int err)
{}

/* see o2net_register_callbacks() */
static void o2net_data_ready(struct sock *sk)
{}

/* see o2net_register_callbacks() */
static void o2net_state_change(struct sock *sk)
{}

/*
 * we register callbacks so we can queue work on events before calling
 * the original callbacks.  our callbacks our careful to test user_data
 * to discover when they've reaced with o2net_unregister_callbacks().
 */
static void o2net_register_callbacks(struct sock *sk,
				     struct o2net_sock_container *sc)
{}

static int o2net_unregister_callbacks(struct sock *sk,
			           struct o2net_sock_container *sc)
{}

/*
 * this is a little helper that is called by callers who have seen a problem
 * with an sc and want to detach it from the nn if someone already hasn't beat
 * them to it.  if an error is given then the shutdown will be persistent
 * and pending transmits will be canceled.
 */
static void o2net_ensure_shutdown(struct o2net_node *nn,
			           struct o2net_sock_container *sc,
				   int err)
{}

/*
 * This work queue function performs the blocking parts of socket shutdown.  A
 * few paths lead here.  set_nn_state will trigger this callback if it sees an
 * sc detached from the nn.  state_change will also trigger this callback
 * directly when it sees errors.  In that case we need to call set_nn_state
 * ourselves as state_change couldn't get the nn_lock and call set_nn_state
 * itself.
 */
static void o2net_shutdown_sc(struct work_struct *work)
{}

/* ------------------------------------------------------------ */

static int o2net_handler_cmp(struct o2net_msg_handler *nmh, u32 msg_type,
			     u32 key)
{}

static struct o2net_msg_handler *
o2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p,
			  struct rb_node **ret_parent)
{}

static void o2net_handler_kref_release(struct kref *kref)
{}

static void o2net_handler_put(struct o2net_msg_handler *nmh)
{}

/* max_len is protection for the handler func.  incoming messages won't
 * be given to the handler if their payload is longer than the max. */
int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
			   o2net_msg_handler_func *func, void *data,
			   o2net_post_msg_handler_func *post_func,
			   struct list_head *unreg_list)
{}
EXPORT_SYMBOL_GPL();

void o2net_unregister_handler_list(struct list_head *list)
{}
EXPORT_SYMBOL_GPL();

static struct o2net_msg_handler *o2net_handler_get(u32 msg_type, u32 key)
{}

/* ------------------------------------------------------------ */

static int o2net_recv_tcp_msg(struct socket *sock, void *data, size_t len)
{}

static int o2net_send_tcp_msg(struct socket *sock, struct kvec *vec,
			      size_t veclen, size_t total)
{}

static void o2net_sendpage(struct o2net_sock_container *sc,
			   void *virt, size_t size)
{}

static void o2net_init_msg(struct o2net_msg *msg, u16 data_len, u16 msg_type, u32 key)
{}

static int o2net_tx_can_proceed(struct o2net_node *nn,
			        struct o2net_sock_container **sc_ret,
				int *error)
{}

/* Get a map of all nodes to which this node is currently connected to */
void o2net_fill_node_map(unsigned long *map, unsigned int bits)
{}
EXPORT_SYMBOL_GPL();

int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
			   size_t caller_veclen, u8 target_node, int *status)
{}
EXPORT_SYMBOL_GPL();

int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len,
		       u8 target_node, int *status)
{}
EXPORT_SYMBOL_GPL();

static int o2net_send_status_magic(struct socket *sock, struct o2net_msg *hdr,
				   enum o2net_system_error syserr, int err)
{}

/* this returns -errno if the header was unknown or too large, etc.
 * after this is called the buffer us reused for the next message */
static int o2net_process_message(struct o2net_sock_container *sc,
				 struct o2net_msg *hdr)
{}

static int o2net_check_handshake(struct o2net_sock_container *sc)
{}

/* this demuxes the queued rx bytes into header or payload bits and calls
 * handlers as each full message is read off the socket.  it returns -error,
 * == 0 eof, or > 0 for progress made.*/
static int o2net_advance_rx(struct o2net_sock_container *sc)
{}

/* this work func is triggerd by data ready.  it reads until it can read no
 * more.  it interprets 0, eof, as fatal.  if data_ready hits while we're doing
 * our work the work struct will be marked and we'll be called again. */
static void o2net_rx_until_empty(struct work_struct *work)
{}

static void o2net_initialize_handshake(void)
{}

/* ------------------------------------------------------------ */

/* called when a connect completes and after a sock is accepted.  the
 * rx path will see the response and mark the sc valid */
static void o2net_sc_connect_completed(struct work_struct *work)
{}

/* this is called as a work_struct func. */
static void o2net_sc_send_keep_req(struct work_struct *work)
{}

/* socket shutdown does a del_timer_sync against this as it tears down.
 * we can't start this timer until we've got to the point in sc buildup
 * where shutdown is going to be involved */
static void o2net_idle_timer(struct timer_list *t)
{}

static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc)
{}

static void o2net_sc_postpone_idle(struct o2net_sock_container *sc)
{}

/* this work func is kicked whenever a path sets the nn state which doesn't
 * have valid set.  This includes seeing hb come up, losing a connection,
 * having a connect attempt fail, etc. This centralizes the logic which decides
 * if a connect attempt should be made or if we should give up and all future
 * transmit attempts should fail */
static void o2net_start_connect(struct work_struct *work)
{}

static void o2net_connect_expired(struct work_struct *work)
{}

static void o2net_still_up(struct work_struct *work)
{}

/* ------------------------------------------------------------ */

void o2net_disconnect_node(struct o2nm_node *node)
{}

static void o2net_hb_node_down_cb(struct o2nm_node *node, int node_num,
				  void *data)
{}

static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
				void *data)
{}

void o2net_unregister_hb_callbacks(void)
{}

int o2net_register_hb_callbacks(void)
{}

/* ------------------------------------------------------------ */

static int o2net_accept_one(struct socket *sock, int *more)
{}

/*
 * This function is invoked in response to one or more
 * pending accepts at softIRQ level. We must drain the
 * entire que before returning.
 */

static void o2net_accept_many(struct work_struct *work)
{}

static void o2net_listen_data_ready(struct sock *sk)
{}

static int o2net_open_listening_sock(__be32 addr, __be16 port)
{}

/*
 * called from node manager when we should bring up our network listening
 * socket.  node manager handles all the serialization to only call this
 * once and to match it with o2net_stop_listening().  note,
 * o2nm_this_node() doesn't work yet as we're being called while it
 * is being set up.
 */
int o2net_start_listening(struct o2nm_node *node)
{}

/* again, o2nm_this_node() doesn't work here as we're involved in
 * tearing it down */
void o2net_stop_listening(struct o2nm_node *node)
{}

/* ------------------------------------------------------------ */

int o2net_init(void)
{}

void o2net_exit(void)
{}