18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/* -*- mode: c; c-basic-offset: 8; -*-
38c2ecf20Sopenharmony_ci * vim: noexpandtab sw=8 ts=8 sts=0:
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * stackglue.h
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Glue to the underlying cluster stack.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (C) 2007 Oracle.  All rights reserved.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifndef STACKGLUE_H
148c2ecf20Sopenharmony_ci#define STACKGLUE_H
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <linux/types.h>
178c2ecf20Sopenharmony_ci#include <linux/list.h>
188c2ecf20Sopenharmony_ci#include <linux/dlmconstants.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include "dlm/dlmapi.h"
218c2ecf20Sopenharmony_ci#include <linux/dlm.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* Needed for plock-related prototypes */
248c2ecf20Sopenharmony_cistruct file;
258c2ecf20Sopenharmony_cistruct file_lock;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/*
288c2ecf20Sopenharmony_ci * dlmconstants.h does not have a LOCAL flag.  We hope to remove it
298c2ecf20Sopenharmony_ci * some day, but right now we need it.  Let's fake it.  This value is larger
308c2ecf20Sopenharmony_ci * than any flag in dlmconstants.h.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#define DLM_LKF_LOCAL		0x00100000
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/*
358c2ecf20Sopenharmony_ci * This shadows DLM_LOCKSPACE_LEN in fs/dlm/dlm_internal.h.  That probably
368c2ecf20Sopenharmony_ci * wants to be in a public header.
378c2ecf20Sopenharmony_ci */
388c2ecf20Sopenharmony_ci#define GROUP_NAME_MAX		64
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/* This shadows  OCFS2_CLUSTER_NAME_LEN */
418c2ecf20Sopenharmony_ci#define CLUSTER_NAME_MAX	16
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci/*
458c2ecf20Sopenharmony_ci * ocfs2_protocol_version changes when ocfs2 does something different in
468c2ecf20Sopenharmony_ci * its inter-node behavior.  See dlmglue.c for more information.
478c2ecf20Sopenharmony_ci */
488c2ecf20Sopenharmony_cistruct ocfs2_protocol_version {
498c2ecf20Sopenharmony_ci	u8 pv_major;
508c2ecf20Sopenharmony_ci	u8 pv_minor;
518c2ecf20Sopenharmony_ci};
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/*
548c2ecf20Sopenharmony_ci * The dlm_lockstatus struct includes lvb space, but the dlm_lksb struct only
558c2ecf20Sopenharmony_ci * has a pointer to separately allocated lvb space.  This struct exists only to
568c2ecf20Sopenharmony_ci * include in the lksb union to make space for a combined dlm_lksb and lvb.
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_cistruct fsdlm_lksb_plus_lvb {
598c2ecf20Sopenharmony_ci	struct dlm_lksb lksb;
608c2ecf20Sopenharmony_ci	char lvb[DLM_LVB_LEN];
618c2ecf20Sopenharmony_ci};
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/*
648c2ecf20Sopenharmony_ci * A union of all lock status structures.  We define it here so that the
658c2ecf20Sopenharmony_ci * size of the union is known.  Lock status structures are embedded in
668c2ecf20Sopenharmony_ci * ocfs2 inodes.
678c2ecf20Sopenharmony_ci */
688c2ecf20Sopenharmony_cistruct ocfs2_cluster_connection;
698c2ecf20Sopenharmony_cistruct ocfs2_dlm_lksb {
708c2ecf20Sopenharmony_ci	 union {
718c2ecf20Sopenharmony_ci		 struct dlm_lockstatus lksb_o2dlm;
728c2ecf20Sopenharmony_ci		 struct dlm_lksb lksb_fsdlm;
738c2ecf20Sopenharmony_ci		 struct fsdlm_lksb_plus_lvb padding;
748c2ecf20Sopenharmony_ci	 };
758c2ecf20Sopenharmony_ci	 struct ocfs2_cluster_connection *lksb_conn;
768c2ecf20Sopenharmony_ci};
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/*
798c2ecf20Sopenharmony_ci * The ocfs2_locking_protocol defines the handlers called on ocfs2's behalf.
808c2ecf20Sopenharmony_ci */
818c2ecf20Sopenharmony_cistruct ocfs2_locking_protocol {
828c2ecf20Sopenharmony_ci	struct ocfs2_protocol_version lp_max_version;
838c2ecf20Sopenharmony_ci	void (*lp_lock_ast)(struct ocfs2_dlm_lksb *lksb);
848c2ecf20Sopenharmony_ci	void (*lp_blocking_ast)(struct ocfs2_dlm_lksb *lksb, int level);
858c2ecf20Sopenharmony_ci	void (*lp_unlock_ast)(struct ocfs2_dlm_lksb *lksb, int error);
868c2ecf20Sopenharmony_ci};
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/*
908c2ecf20Sopenharmony_ci * A cluster connection.  Mostly opaque to ocfs2, the connection holds
918c2ecf20Sopenharmony_ci * state for the underlying stack.  ocfs2 does use cc_version to determine
928c2ecf20Sopenharmony_ci * locking compatibility.
938c2ecf20Sopenharmony_ci */
948c2ecf20Sopenharmony_cistruct ocfs2_cluster_connection {
958c2ecf20Sopenharmony_ci	char cc_name[GROUP_NAME_MAX + 1];
968c2ecf20Sopenharmony_ci	int cc_namelen;
978c2ecf20Sopenharmony_ci	char cc_cluster_name[CLUSTER_NAME_MAX + 1];
988c2ecf20Sopenharmony_ci	int cc_cluster_name_len;
998c2ecf20Sopenharmony_ci	struct ocfs2_protocol_version cc_version;
1008c2ecf20Sopenharmony_ci	struct ocfs2_locking_protocol *cc_proto;
1018c2ecf20Sopenharmony_ci	void (*cc_recovery_handler)(int node_num, void *recovery_data);
1028c2ecf20Sopenharmony_ci	void *cc_recovery_data;
1038c2ecf20Sopenharmony_ci	void *cc_lockspace;
1048c2ecf20Sopenharmony_ci	void *cc_private;
1058c2ecf20Sopenharmony_ci};
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci/*
1088c2ecf20Sopenharmony_ci * Each cluster stack implements the stack operations structure.  Not used
1098c2ecf20Sopenharmony_ci * in the ocfs2 code, the stackglue code translates generic cluster calls
1108c2ecf20Sopenharmony_ci * into stack operations.
1118c2ecf20Sopenharmony_ci */
1128c2ecf20Sopenharmony_cistruct ocfs2_stack_operations {
1138c2ecf20Sopenharmony_ci	/*
1148c2ecf20Sopenharmony_ci	 * The fs code calls ocfs2_cluster_connect() to attach a new
1158c2ecf20Sopenharmony_ci	 * filesystem to the cluster stack.  The ->connect() op is passed
1168c2ecf20Sopenharmony_ci	 * an ocfs2_cluster_connection with the name and recovery field
1178c2ecf20Sopenharmony_ci	 * filled in.
1188c2ecf20Sopenharmony_ci	 *
1198c2ecf20Sopenharmony_ci	 * The stack must set up any notification mechanisms and create
1208c2ecf20Sopenharmony_ci	 * the filesystem lockspace in the DLM.  The lockspace should be
1218c2ecf20Sopenharmony_ci	 * stored on cc_lockspace.  Any other information can be stored on
1228c2ecf20Sopenharmony_ci	 * cc_private.
1238c2ecf20Sopenharmony_ci	 *
1248c2ecf20Sopenharmony_ci	 * ->connect() must not return until it is guaranteed that
1258c2ecf20Sopenharmony_ci	 *
1268c2ecf20Sopenharmony_ci	 *  - Node down notifications for the filesystem will be received
1278c2ecf20Sopenharmony_ci	 *    and passed to conn->cc_recovery_handler().
1288c2ecf20Sopenharmony_ci	 *  - Locking requests for the filesystem will be processed.
1298c2ecf20Sopenharmony_ci	 */
1308c2ecf20Sopenharmony_ci	int (*connect)(struct ocfs2_cluster_connection *conn);
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	/*
1338c2ecf20Sopenharmony_ci	 * The fs code calls ocfs2_cluster_disconnect() when a filesystem
1348c2ecf20Sopenharmony_ci	 * no longer needs cluster services.  All DLM locks have been
1358c2ecf20Sopenharmony_ci	 * dropped, and recovery notification is being ignored by the
1368c2ecf20Sopenharmony_ci	 * fs code.  The stack must disengage from the DLM and discontinue
1378c2ecf20Sopenharmony_ci	 * recovery notification.
1388c2ecf20Sopenharmony_ci	 *
1398c2ecf20Sopenharmony_ci	 * Once ->disconnect() has returned, the connection structure will
1408c2ecf20Sopenharmony_ci	 * be freed.  Thus, a stack must not return from ->disconnect()
1418c2ecf20Sopenharmony_ci	 * until it will no longer reference the conn pointer.
1428c2ecf20Sopenharmony_ci	 *
1438c2ecf20Sopenharmony_ci	 * Once this call returns, the stack glue will be dropping this
1448c2ecf20Sopenharmony_ci	 * connection's reference on the module.
1458c2ecf20Sopenharmony_ci	 */
1468c2ecf20Sopenharmony_ci	int (*disconnect)(struct ocfs2_cluster_connection *conn);
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	/*
1498c2ecf20Sopenharmony_ci	 * ->this_node() returns the cluster's unique identifier for the
1508c2ecf20Sopenharmony_ci	 * local node.
1518c2ecf20Sopenharmony_ci	 */
1528c2ecf20Sopenharmony_ci	int (*this_node)(struct ocfs2_cluster_connection *conn,
1538c2ecf20Sopenharmony_ci			 unsigned int *node);
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	/*
1568c2ecf20Sopenharmony_ci	 * Call the underlying dlm lock function.  The ->dlm_lock()
1578c2ecf20Sopenharmony_ci	 * callback should convert the flags and mode as appropriate.
1588c2ecf20Sopenharmony_ci	 *
1598c2ecf20Sopenharmony_ci	 * ast and bast functions are not part of the call because the
1608c2ecf20Sopenharmony_ci	 * stack will likely want to wrap ast and bast calls before passing
1618c2ecf20Sopenharmony_ci	 * them to stack->sp_proto.  There is no astarg.  The lksb will
1628c2ecf20Sopenharmony_ci	 * be passed back to the ast and bast functions.  The caller can
1638c2ecf20Sopenharmony_ci	 * use this to find their object.
1648c2ecf20Sopenharmony_ci	 */
1658c2ecf20Sopenharmony_ci	int (*dlm_lock)(struct ocfs2_cluster_connection *conn,
1668c2ecf20Sopenharmony_ci			int mode,
1678c2ecf20Sopenharmony_ci			struct ocfs2_dlm_lksb *lksb,
1688c2ecf20Sopenharmony_ci			u32 flags,
1698c2ecf20Sopenharmony_ci			void *name,
1708c2ecf20Sopenharmony_ci			unsigned int namelen);
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/*
1738c2ecf20Sopenharmony_ci	 * Call the underlying dlm unlock function.  The ->dlm_unlock()
1748c2ecf20Sopenharmony_ci	 * function should convert the flags as appropriate.
1758c2ecf20Sopenharmony_ci	 *
1768c2ecf20Sopenharmony_ci	 * The unlock ast is not passed, as the stack will want to wrap
1778c2ecf20Sopenharmony_ci	 * it before calling stack->sp_proto->lp_unlock_ast().  There is
1788c2ecf20Sopenharmony_ci	 * no astarg.  The lksb will be passed back to the unlock ast
1798c2ecf20Sopenharmony_ci	 * function.  The caller can use this to find their object.
1808c2ecf20Sopenharmony_ci	 */
1818c2ecf20Sopenharmony_ci	int (*dlm_unlock)(struct ocfs2_cluster_connection *conn,
1828c2ecf20Sopenharmony_ci			  struct ocfs2_dlm_lksb *lksb,
1838c2ecf20Sopenharmony_ci			  u32 flags);
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	/*
1868c2ecf20Sopenharmony_ci	 * Return the status of the current lock status block.  The fs
1878c2ecf20Sopenharmony_ci	 * code should never dereference the union.  The ->lock_status()
1888c2ecf20Sopenharmony_ci	 * callback pulls out the stack-specific lksb, converts the status
1898c2ecf20Sopenharmony_ci	 * to a proper errno, and returns it.
1908c2ecf20Sopenharmony_ci	 */
1918c2ecf20Sopenharmony_ci	int (*lock_status)(struct ocfs2_dlm_lksb *lksb);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	/*
1948c2ecf20Sopenharmony_ci	 * Return non-zero if the LVB is valid.
1958c2ecf20Sopenharmony_ci	 */
1968c2ecf20Sopenharmony_ci	int (*lvb_valid)(struct ocfs2_dlm_lksb *lksb);
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	/*
1998c2ecf20Sopenharmony_ci	 * Pull the lvb pointer off of the stack-specific lksb.
2008c2ecf20Sopenharmony_ci	 */
2018c2ecf20Sopenharmony_ci	void *(*lock_lvb)(struct ocfs2_dlm_lksb *lksb);
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	/*
2048c2ecf20Sopenharmony_ci	 * Cluster-aware posix locks
2058c2ecf20Sopenharmony_ci	 *
2068c2ecf20Sopenharmony_ci	 * This is NULL for stacks which do not support posix locks.
2078c2ecf20Sopenharmony_ci	 */
2088c2ecf20Sopenharmony_ci	int (*plock)(struct ocfs2_cluster_connection *conn,
2098c2ecf20Sopenharmony_ci		     u64 ino,
2108c2ecf20Sopenharmony_ci		     struct file *file,
2118c2ecf20Sopenharmony_ci		     int cmd,
2128c2ecf20Sopenharmony_ci		     struct file_lock *fl);
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	/*
2158c2ecf20Sopenharmony_ci	 * This is an optoinal debugging hook.  If provided, the
2168c2ecf20Sopenharmony_ci	 * stack can dump debugging information about this lock.
2178c2ecf20Sopenharmony_ci	 */
2188c2ecf20Sopenharmony_ci	void (*dump_lksb)(struct ocfs2_dlm_lksb *lksb);
2198c2ecf20Sopenharmony_ci};
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci/*
2228c2ecf20Sopenharmony_ci * Each stack plugin must describe itself by registering a
2238c2ecf20Sopenharmony_ci * ocfs2_stack_plugin structure.  This is only seen by stackglue and the
2248c2ecf20Sopenharmony_ci * stack driver.
2258c2ecf20Sopenharmony_ci */
2268c2ecf20Sopenharmony_cistruct ocfs2_stack_plugin {
2278c2ecf20Sopenharmony_ci	char *sp_name;
2288c2ecf20Sopenharmony_ci	struct ocfs2_stack_operations *sp_ops;
2298c2ecf20Sopenharmony_ci	struct module *sp_owner;
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	/* These are managed by the stackglue code. */
2328c2ecf20Sopenharmony_ci	struct list_head sp_list;
2338c2ecf20Sopenharmony_ci	unsigned int sp_count;
2348c2ecf20Sopenharmony_ci	struct ocfs2_protocol_version sp_max_proto;
2358c2ecf20Sopenharmony_ci};
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci/* Used by the filesystem */
2398c2ecf20Sopenharmony_ciint ocfs2_cluster_connect(const char *stack_name,
2408c2ecf20Sopenharmony_ci			  const char *cluster_name,
2418c2ecf20Sopenharmony_ci			  int cluster_name_len,
2428c2ecf20Sopenharmony_ci			  const char *group,
2438c2ecf20Sopenharmony_ci			  int grouplen,
2448c2ecf20Sopenharmony_ci			  struct ocfs2_locking_protocol *lproto,
2458c2ecf20Sopenharmony_ci			  void (*recovery_handler)(int node_num,
2468c2ecf20Sopenharmony_ci						   void *recovery_data),
2478c2ecf20Sopenharmony_ci			  void *recovery_data,
2488c2ecf20Sopenharmony_ci			  struct ocfs2_cluster_connection **conn);
2498c2ecf20Sopenharmony_ci/*
2508c2ecf20Sopenharmony_ci * Used by callers that don't store their stack name.  They must ensure
2518c2ecf20Sopenharmony_ci * all nodes have the same stack.
2528c2ecf20Sopenharmony_ci */
2538c2ecf20Sopenharmony_ciint ocfs2_cluster_connect_agnostic(const char *group,
2548c2ecf20Sopenharmony_ci				   int grouplen,
2558c2ecf20Sopenharmony_ci				   struct ocfs2_locking_protocol *lproto,
2568c2ecf20Sopenharmony_ci				   void (*recovery_handler)(int node_num,
2578c2ecf20Sopenharmony_ci							    void *recovery_data),
2588c2ecf20Sopenharmony_ci				   void *recovery_data,
2598c2ecf20Sopenharmony_ci				   struct ocfs2_cluster_connection **conn);
2608c2ecf20Sopenharmony_ciint ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
2618c2ecf20Sopenharmony_ci			     int hangup_pending);
2628c2ecf20Sopenharmony_civoid ocfs2_cluster_hangup(const char *group, int grouplen);
2638c2ecf20Sopenharmony_ciint ocfs2_cluster_this_node(struct ocfs2_cluster_connection *conn,
2648c2ecf20Sopenharmony_ci			    unsigned int *node);
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_cistruct ocfs2_lock_res;
2678c2ecf20Sopenharmony_ciint ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
2688c2ecf20Sopenharmony_ci		   int mode,
2698c2ecf20Sopenharmony_ci		   struct ocfs2_dlm_lksb *lksb,
2708c2ecf20Sopenharmony_ci		   u32 flags,
2718c2ecf20Sopenharmony_ci		   void *name,
2728c2ecf20Sopenharmony_ci		   unsigned int namelen);
2738c2ecf20Sopenharmony_ciint ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
2748c2ecf20Sopenharmony_ci		     struct ocfs2_dlm_lksb *lksb,
2758c2ecf20Sopenharmony_ci		     u32 flags);
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ciint ocfs2_dlm_lock_status(struct ocfs2_dlm_lksb *lksb);
2788c2ecf20Sopenharmony_ciint ocfs2_dlm_lvb_valid(struct ocfs2_dlm_lksb *lksb);
2798c2ecf20Sopenharmony_civoid *ocfs2_dlm_lvb(struct ocfs2_dlm_lksb *lksb);
2808c2ecf20Sopenharmony_civoid ocfs2_dlm_dump_lksb(struct ocfs2_dlm_lksb *lksb);
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ciint ocfs2_stack_supports_plocks(void);
2838c2ecf20Sopenharmony_ciint ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino,
2848c2ecf20Sopenharmony_ci		struct file *file, int cmd, struct file_lock *fl);
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_civoid ocfs2_stack_glue_set_max_proto_version(struct ocfs2_protocol_version *max_proto);
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci/* Used by stack plugins */
2908c2ecf20Sopenharmony_ciint ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin);
2918c2ecf20Sopenharmony_civoid ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin);
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ciextern struct kset *ocfs2_kset;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci#endif  /* STACKGLUE_H */
296