162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * stackglue.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Glue to the underlying cluster stack.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2007 Oracle.  All rights reserved.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef STACKGLUE_H
1262306a36Sopenharmony_ci#define STACKGLUE_H
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/types.h>
1562306a36Sopenharmony_ci#include <linux/list.h>
1662306a36Sopenharmony_ci#include <linux/dlmconstants.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "dlm/dlmapi.h"
1962306a36Sopenharmony_ci#include <linux/dlm.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* Needed for plock-related prototypes */
2262306a36Sopenharmony_cistruct file;
2362306a36Sopenharmony_cistruct file_lock;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/*
2662306a36Sopenharmony_ci * dlmconstants.h does not have a LOCAL flag.  We hope to remove it
2762306a36Sopenharmony_ci * some day, but right now we need it.  Let's fake it.  This value is larger
2862306a36Sopenharmony_ci * than any flag in dlmconstants.h.
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_ci#define DLM_LKF_LOCAL		0x00100000
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci * This shadows DLM_LOCKSPACE_LEN in fs/dlm/dlm_internal.h.  That probably
3462306a36Sopenharmony_ci * wants to be in a public header.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_ci#define GROUP_NAME_MAX		64
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/* This shadows  OCFS2_CLUSTER_NAME_LEN */
3962306a36Sopenharmony_ci#define CLUSTER_NAME_MAX	16
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/*
4362306a36Sopenharmony_ci * ocfs2_protocol_version changes when ocfs2 does something different in
4462306a36Sopenharmony_ci * its inter-node behavior.  See dlmglue.c for more information.
4562306a36Sopenharmony_ci */
4662306a36Sopenharmony_cistruct ocfs2_protocol_version {
4762306a36Sopenharmony_ci	u8 pv_major;
4862306a36Sopenharmony_ci	u8 pv_minor;
4962306a36Sopenharmony_ci};
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/*
5262306a36Sopenharmony_ci * The dlm_lockstatus struct includes lvb space, but the dlm_lksb struct only
5362306a36Sopenharmony_ci * has a pointer to separately allocated lvb space.  This struct exists only to
5462306a36Sopenharmony_ci * include in the lksb union to make space for a combined dlm_lksb and lvb.
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_cistruct fsdlm_lksb_plus_lvb {
5762306a36Sopenharmony_ci	struct dlm_lksb lksb;
5862306a36Sopenharmony_ci	char lvb[DLM_LVB_LEN];
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/*
6262306a36Sopenharmony_ci * A union of all lock status structures.  We define it here so that the
6362306a36Sopenharmony_ci * size of the union is known.  Lock status structures are embedded in
6462306a36Sopenharmony_ci * ocfs2 inodes.
6562306a36Sopenharmony_ci */
6662306a36Sopenharmony_cistruct ocfs2_cluster_connection;
6762306a36Sopenharmony_cistruct ocfs2_dlm_lksb {
6862306a36Sopenharmony_ci	 union {
6962306a36Sopenharmony_ci		 struct dlm_lockstatus lksb_o2dlm;
7062306a36Sopenharmony_ci		 struct dlm_lksb lksb_fsdlm;
7162306a36Sopenharmony_ci		 struct fsdlm_lksb_plus_lvb padding;
7262306a36Sopenharmony_ci	 };
7362306a36Sopenharmony_ci	 struct ocfs2_cluster_connection *lksb_conn;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/*
7762306a36Sopenharmony_ci * The ocfs2_locking_protocol defines the handlers called on ocfs2's behalf.
7862306a36Sopenharmony_ci */
7962306a36Sopenharmony_cistruct ocfs2_locking_protocol {
8062306a36Sopenharmony_ci	struct ocfs2_protocol_version lp_max_version;
8162306a36Sopenharmony_ci	void (*lp_lock_ast)(struct ocfs2_dlm_lksb *lksb);
8262306a36Sopenharmony_ci	void (*lp_blocking_ast)(struct ocfs2_dlm_lksb *lksb, int level);
8362306a36Sopenharmony_ci	void (*lp_unlock_ast)(struct ocfs2_dlm_lksb *lksb, int error);
8462306a36Sopenharmony_ci};
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/*
8862306a36Sopenharmony_ci * A cluster connection.  Mostly opaque to ocfs2, the connection holds
8962306a36Sopenharmony_ci * state for the underlying stack.  ocfs2 does use cc_version to determine
9062306a36Sopenharmony_ci * locking compatibility.
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_cistruct ocfs2_cluster_connection {
9362306a36Sopenharmony_ci	char cc_name[GROUP_NAME_MAX + 1];
9462306a36Sopenharmony_ci	int cc_namelen;
9562306a36Sopenharmony_ci	char cc_cluster_name[CLUSTER_NAME_MAX + 1];
9662306a36Sopenharmony_ci	int cc_cluster_name_len;
9762306a36Sopenharmony_ci	struct ocfs2_protocol_version cc_version;
9862306a36Sopenharmony_ci	struct ocfs2_locking_protocol *cc_proto;
9962306a36Sopenharmony_ci	void (*cc_recovery_handler)(int node_num, void *recovery_data);
10062306a36Sopenharmony_ci	void *cc_recovery_data;
10162306a36Sopenharmony_ci	void *cc_lockspace;
10262306a36Sopenharmony_ci	void *cc_private;
10362306a36Sopenharmony_ci};
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/*
10662306a36Sopenharmony_ci * Each cluster stack implements the stack operations structure.  Not used
10762306a36Sopenharmony_ci * in the ocfs2 code, the stackglue code translates generic cluster calls
10862306a36Sopenharmony_ci * into stack operations.
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_cistruct ocfs2_stack_operations {
11162306a36Sopenharmony_ci	/*
11262306a36Sopenharmony_ci	 * The fs code calls ocfs2_cluster_connect() to attach a new
11362306a36Sopenharmony_ci	 * filesystem to the cluster stack.  The ->connect() op is passed
11462306a36Sopenharmony_ci	 * an ocfs2_cluster_connection with the name and recovery field
11562306a36Sopenharmony_ci	 * filled in.
11662306a36Sopenharmony_ci	 *
11762306a36Sopenharmony_ci	 * The stack must set up any notification mechanisms and create
11862306a36Sopenharmony_ci	 * the filesystem lockspace in the DLM.  The lockspace should be
11962306a36Sopenharmony_ci	 * stored on cc_lockspace.  Any other information can be stored on
12062306a36Sopenharmony_ci	 * cc_private.
12162306a36Sopenharmony_ci	 *
12262306a36Sopenharmony_ci	 * ->connect() must not return until it is guaranteed that
12362306a36Sopenharmony_ci	 *
12462306a36Sopenharmony_ci	 *  - Node down notifications for the filesystem will be received
12562306a36Sopenharmony_ci	 *    and passed to conn->cc_recovery_handler().
12662306a36Sopenharmony_ci	 *  - Locking requests for the filesystem will be processed.
12762306a36Sopenharmony_ci	 */
12862306a36Sopenharmony_ci	int (*connect)(struct ocfs2_cluster_connection *conn);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	/*
13162306a36Sopenharmony_ci	 * The fs code calls ocfs2_cluster_disconnect() when a filesystem
13262306a36Sopenharmony_ci	 * no longer needs cluster services.  All DLM locks have been
13362306a36Sopenharmony_ci	 * dropped, and recovery notification is being ignored by the
13462306a36Sopenharmony_ci	 * fs code.  The stack must disengage from the DLM and discontinue
13562306a36Sopenharmony_ci	 * recovery notification.
13662306a36Sopenharmony_ci	 *
13762306a36Sopenharmony_ci	 * Once ->disconnect() has returned, the connection structure will
13862306a36Sopenharmony_ci	 * be freed.  Thus, a stack must not return from ->disconnect()
13962306a36Sopenharmony_ci	 * until it will no longer reference the conn pointer.
14062306a36Sopenharmony_ci	 *
14162306a36Sopenharmony_ci	 * Once this call returns, the stack glue will be dropping this
14262306a36Sopenharmony_ci	 * connection's reference on the module.
14362306a36Sopenharmony_ci	 */
14462306a36Sopenharmony_ci	int (*disconnect)(struct ocfs2_cluster_connection *conn);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/*
14762306a36Sopenharmony_ci	 * ->this_node() returns the cluster's unique identifier for the
14862306a36Sopenharmony_ci	 * local node.
14962306a36Sopenharmony_ci	 */
15062306a36Sopenharmony_ci	int (*this_node)(struct ocfs2_cluster_connection *conn,
15162306a36Sopenharmony_ci			 unsigned int *node);
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	/*
15462306a36Sopenharmony_ci	 * Call the underlying dlm lock function.  The ->dlm_lock()
15562306a36Sopenharmony_ci	 * callback should convert the flags and mode as appropriate.
15662306a36Sopenharmony_ci	 *
15762306a36Sopenharmony_ci	 * ast and bast functions are not part of the call because the
15862306a36Sopenharmony_ci	 * stack will likely want to wrap ast and bast calls before passing
15962306a36Sopenharmony_ci	 * them to stack->sp_proto.  There is no astarg.  The lksb will
16062306a36Sopenharmony_ci	 * be passed back to the ast and bast functions.  The caller can
16162306a36Sopenharmony_ci	 * use this to find their object.
16262306a36Sopenharmony_ci	 */
16362306a36Sopenharmony_ci	int (*dlm_lock)(struct ocfs2_cluster_connection *conn,
16462306a36Sopenharmony_ci			int mode,
16562306a36Sopenharmony_ci			struct ocfs2_dlm_lksb *lksb,
16662306a36Sopenharmony_ci			u32 flags,
16762306a36Sopenharmony_ci			void *name,
16862306a36Sopenharmony_ci			unsigned int namelen);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	/*
17162306a36Sopenharmony_ci	 * Call the underlying dlm unlock function.  The ->dlm_unlock()
17262306a36Sopenharmony_ci	 * function should convert the flags as appropriate.
17362306a36Sopenharmony_ci	 *
17462306a36Sopenharmony_ci	 * The unlock ast is not passed, as the stack will want to wrap
17562306a36Sopenharmony_ci	 * it before calling stack->sp_proto->lp_unlock_ast().  There is
17662306a36Sopenharmony_ci	 * no astarg.  The lksb will be passed back to the unlock ast
17762306a36Sopenharmony_ci	 * function.  The caller can use this to find their object.
17862306a36Sopenharmony_ci	 */
17962306a36Sopenharmony_ci	int (*dlm_unlock)(struct ocfs2_cluster_connection *conn,
18062306a36Sopenharmony_ci			  struct ocfs2_dlm_lksb *lksb,
18162306a36Sopenharmony_ci			  u32 flags);
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	/*
18462306a36Sopenharmony_ci	 * Return the status of the current lock status block.  The fs
18562306a36Sopenharmony_ci	 * code should never dereference the union.  The ->lock_status()
18662306a36Sopenharmony_ci	 * callback pulls out the stack-specific lksb, converts the status
18762306a36Sopenharmony_ci	 * to a proper errno, and returns it.
18862306a36Sopenharmony_ci	 */
18962306a36Sopenharmony_ci	int (*lock_status)(struct ocfs2_dlm_lksb *lksb);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	/*
19262306a36Sopenharmony_ci	 * Return non-zero if the LVB is valid.
19362306a36Sopenharmony_ci	 */
19462306a36Sopenharmony_ci	int (*lvb_valid)(struct ocfs2_dlm_lksb *lksb);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	/*
19762306a36Sopenharmony_ci	 * Pull the lvb pointer off of the stack-specific lksb.
19862306a36Sopenharmony_ci	 */
19962306a36Sopenharmony_ci	void *(*lock_lvb)(struct ocfs2_dlm_lksb *lksb);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	/*
20262306a36Sopenharmony_ci	 * Cluster-aware posix locks
20362306a36Sopenharmony_ci	 *
20462306a36Sopenharmony_ci	 * This is NULL for stacks which do not support posix locks.
20562306a36Sopenharmony_ci	 */
20662306a36Sopenharmony_ci	int (*plock)(struct ocfs2_cluster_connection *conn,
20762306a36Sopenharmony_ci		     u64 ino,
20862306a36Sopenharmony_ci		     struct file *file,
20962306a36Sopenharmony_ci		     int cmd,
21062306a36Sopenharmony_ci		     struct file_lock *fl);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/*
21362306a36Sopenharmony_ci	 * This is an optoinal debugging hook.  If provided, the
21462306a36Sopenharmony_ci	 * stack can dump debugging information about this lock.
21562306a36Sopenharmony_ci	 */
21662306a36Sopenharmony_ci	void (*dump_lksb)(struct ocfs2_dlm_lksb *lksb);
21762306a36Sopenharmony_ci};
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci/*
22062306a36Sopenharmony_ci * Each stack plugin must describe itself by registering a
22162306a36Sopenharmony_ci * ocfs2_stack_plugin structure.  This is only seen by stackglue and the
22262306a36Sopenharmony_ci * stack driver.
22362306a36Sopenharmony_ci */
22462306a36Sopenharmony_cistruct ocfs2_stack_plugin {
22562306a36Sopenharmony_ci	char *sp_name;
22662306a36Sopenharmony_ci	struct ocfs2_stack_operations *sp_ops;
22762306a36Sopenharmony_ci	struct module *sp_owner;
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	/* These are managed by the stackglue code. */
23062306a36Sopenharmony_ci	struct list_head sp_list;
23162306a36Sopenharmony_ci	unsigned int sp_count;
23262306a36Sopenharmony_ci	struct ocfs2_protocol_version sp_max_proto;
23362306a36Sopenharmony_ci};
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci/* Used by the filesystem */
23762306a36Sopenharmony_ciint ocfs2_cluster_connect(const char *stack_name,
23862306a36Sopenharmony_ci			  const char *cluster_name,
23962306a36Sopenharmony_ci			  int cluster_name_len,
24062306a36Sopenharmony_ci			  const char *group,
24162306a36Sopenharmony_ci			  int grouplen,
24262306a36Sopenharmony_ci			  struct ocfs2_locking_protocol *lproto,
24362306a36Sopenharmony_ci			  void (*recovery_handler)(int node_num,
24462306a36Sopenharmony_ci						   void *recovery_data),
24562306a36Sopenharmony_ci			  void *recovery_data,
24662306a36Sopenharmony_ci			  struct ocfs2_cluster_connection **conn);
24762306a36Sopenharmony_ci/*
24862306a36Sopenharmony_ci * Used by callers that don't store their stack name.  They must ensure
24962306a36Sopenharmony_ci * all nodes have the same stack.
25062306a36Sopenharmony_ci */
25162306a36Sopenharmony_ciint ocfs2_cluster_connect_agnostic(const char *group,
25262306a36Sopenharmony_ci				   int grouplen,
25362306a36Sopenharmony_ci				   struct ocfs2_locking_protocol *lproto,
25462306a36Sopenharmony_ci				   void (*recovery_handler)(int node_num,
25562306a36Sopenharmony_ci							    void *recovery_data),
25662306a36Sopenharmony_ci				   void *recovery_data,
25762306a36Sopenharmony_ci				   struct ocfs2_cluster_connection **conn);
25862306a36Sopenharmony_ciint ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
25962306a36Sopenharmony_ci			     int hangup_pending);
26062306a36Sopenharmony_civoid ocfs2_cluster_hangup(const char *group, int grouplen);
26162306a36Sopenharmony_ciint ocfs2_cluster_this_node(struct ocfs2_cluster_connection *conn,
26262306a36Sopenharmony_ci			    unsigned int *node);
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_cistruct ocfs2_lock_res;
26562306a36Sopenharmony_ciint ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
26662306a36Sopenharmony_ci		   int mode,
26762306a36Sopenharmony_ci		   struct ocfs2_dlm_lksb *lksb,
26862306a36Sopenharmony_ci		   u32 flags,
26962306a36Sopenharmony_ci		   void *name,
27062306a36Sopenharmony_ci		   unsigned int namelen);
27162306a36Sopenharmony_ciint ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
27262306a36Sopenharmony_ci		     struct ocfs2_dlm_lksb *lksb,
27362306a36Sopenharmony_ci		     u32 flags);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ciint ocfs2_dlm_lock_status(struct ocfs2_dlm_lksb *lksb);
27662306a36Sopenharmony_ciint ocfs2_dlm_lvb_valid(struct ocfs2_dlm_lksb *lksb);
27762306a36Sopenharmony_civoid *ocfs2_dlm_lvb(struct ocfs2_dlm_lksb *lksb);
27862306a36Sopenharmony_civoid ocfs2_dlm_dump_lksb(struct ocfs2_dlm_lksb *lksb);
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ciint ocfs2_stack_supports_plocks(void);
28162306a36Sopenharmony_ciint ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino,
28262306a36Sopenharmony_ci		struct file *file, int cmd, struct file_lock *fl);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_civoid ocfs2_stack_glue_set_max_proto_version(struct ocfs2_protocol_version *max_proto);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/* Used by stack plugins */
28862306a36Sopenharmony_ciint ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin);
28962306a36Sopenharmony_civoid ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ciextern struct kset *ocfs2_kset;
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci#endif  /* STACKGLUE_H */
294