stackglue.h 7.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/* -*- mode: c; c-basic-offset: 8; -*-
 * vim: noexpandtab sw=8 ts=8 sts=0:
 *
 * stackglue.h
 *
 * Glue to the underlying cluster stack.
 *
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */


#ifndef STACKGLUE_H
#define STACKGLUE_H

24 25 26 27
#include <linux/types.h>
#include <linux/list.h>
#include <linux/dlmconstants.h>

28 29
#include "dlm/dlmapi.h"

30 31 32 33 34 35 36
/*
 * dlmconstants.h does not have a LOCAL flag.  We hope to remove it
 * some day, but right now we need it.  Let's fake it.  This value is larger
 * than any flag in dlmconstants.h.
 */
#define DLM_LKF_LOCAL		0x00100000

37 38 39 40 41 42 43
/*
 * This shadows DLM_LOCKSPACE_LEN in fs/dlm/dlm_internal.h.  That probably
 * wants to be in a public header.
 */
#define GROUP_NAME_MAX		64


44 45 46 47
/*
 * ocfs2_protocol_version changes when ocfs2 does something different in
 * its inter-node behavior.  See dlmglue.c for more information.
 */
48 49 50 51 52
struct ocfs2_protocol_version {
	u8 pv_major;
	u8 pv_minor;
};

53 54 55
/*
 * The ocfs2_locking_protocol defines the handlers called on ocfs2's behalf.
 */
56
struct ocfs2_locking_protocol {
57
	struct ocfs2_protocol_version lp_max_version;
58 59
	void (*lp_lock_ast)(void *astarg);
	void (*lp_blocking_ast)(void *astarg, int level);
60
	void (*lp_unlock_ast)(void *astarg, int error);
61 62
};

63 64 65 66 67
/*
 * A union of all lock status structures.  We define it here so that the
 * size of the union is known.  Lock status structures are embedded in
 * ocfs2 inodes.
 */
68 69 70 71
union ocfs2_dlm_lksb {
	struct dlm_lockstatus lksb_o2dlm;
};

72 73 74 75 76
/*
 * A cluster connection.  Mostly opaque to ocfs2, the connection holds
 * state for the underlying stack.  ocfs2 does use cc_version to determine
 * locking compatibility.
 */
77 78 79 80 81 82 83 84 85 86
struct ocfs2_cluster_connection {
	char cc_name[GROUP_NAME_MAX];
	int cc_namelen;
	struct ocfs2_protocol_version cc_version;
	void (*cc_recovery_handler)(int node_num, void *recovery_data);
	void *cc_recovery_data;
	void *cc_lockspace;
	void *cc_private;
};

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
/*
 * Each cluster stack implements the stack operations structure.  Not used
 * in the ocfs2 code, the stackglue code translates generic cluster calls
 * into stack operations.
 */
struct ocfs2_stack_operations {
	/*
	 * The fs code calls ocfs2_cluster_connect() to attach a new
	 * filesystem to the cluster stack.  The ->connect() op is passed
	 * an ocfs2_cluster_connection with the name and recovery field
	 * filled in.
	 *
	 * The stack must set up any notification mechanisms and create
	 * the filesystem lockspace in the DLM.  The lockspace should be
	 * stored on cc_lockspace.  Any other information can be stored on
	 * cc_private.
	 *
	 * ->connect() must not return until it is guaranteed that
	 *
	 *  - Node down notifications for the filesystem will be recieved
	 *    and passed to conn->cc_recovery_handler().
	 *  - Locking requests for the filesystem will be processed.
	 */
	int (*connect)(struct ocfs2_cluster_connection *conn);

	/*
	 * The fs code calls ocfs2_cluster_disconnect() when a filesystem
	 * no longer needs cluster services.  All DLM locks have been
	 * dropped, and recovery notification is being ignored by the
	 * fs code.  The stack must disengage from the DLM and discontinue
	 * recovery notification.
	 *
	 * Once ->disconnect() has returned, the connection structure will
	 * be freed.  Thus, a stack must not return from ->disconnect()
	 * until it will no longer reference the conn pointer.
122 123 124
	 *
	 * If hangup_pending is zero, ocfs2_cluster_disconnect() will also
	 * be dropping the reference on the module.
125
	 */
126 127
	int (*disconnect)(struct ocfs2_cluster_connection *conn,
			  int hangup_pending);
128 129 130 131 132 133

	/*
	 * ocfs2_cluster_hangup() exists for compatibility with older
	 * ocfs2 tools.  Only the classic stack really needs it.  As such
	 * ->hangup() is not required of all stacks.  See the comment by
	 * ocfs2_cluster_hangup() for more details.
134 135 136
	 *
	 * Note that ocfs2_cluster_hangup() can only be called if
	 * hangup_pending was passed to ocfs2_cluster_disconnect().
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
	 */
	void (*hangup)(const char *group, int grouplen);

	/*
	 * ->this_node() returns the cluster's unique identifier for the
	 * local node.
	 */
	int (*this_node)(unsigned int *node);

	/*
	 * Call the underlying dlm lock function.  The ->dlm_lock()
	 * callback should convert the flags and mode as appropriate.
	 *
	 * ast and bast functions are not part of the call because the
	 * stack will likely want to wrap ast and bast calls before passing
	 * them to stack->sp_proto.
	 */
	int (*dlm_lock)(struct ocfs2_cluster_connection *conn,
			int mode,
			union ocfs2_dlm_lksb *lksb,
			u32 flags,
			void *name,
			unsigned int namelen,
			void *astarg);

	/*
	 * Call the underlying dlm unlock function.  The ->dlm_unlock()
	 * function should convert the flags as appropriate.
	 *
	 * The unlock ast is not passed, as the stack will want to wrap
	 * it before calling stack->sp_proto->lp_unlock_ast().
	 */
	int (*dlm_unlock)(struct ocfs2_cluster_connection *conn,
			  union ocfs2_dlm_lksb *lksb,
			  u32 flags,
			  void *astarg);

	/*
	 * Return the status of the current lock status block.  The fs
	 * code should never dereference the union.  The ->lock_status()
	 * callback pulls out the stack-specific lksb, converts the status
	 * to a proper errno, and returns it.
	 */
	int (*lock_status)(union ocfs2_dlm_lksb *lksb);

	/*
	 * Pull the lvb pointer off of the stack-specific lksb.
	 */
	void *(*lock_lvb)(union ocfs2_dlm_lksb *lksb);

	/*
	 * This is an optoinal debugging hook.  If provided, the
	 * stack can dump debugging information about this lock.
	 */
	void (*dump_lksb)(union ocfs2_dlm_lksb *lksb);
};

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
/*
 * Each stack plugin must describe itself by registering a
 * ocfs2_stack_plugin structure.  This is only seen by stackglue and the
 * stack driver.
 */
struct ocfs2_stack_plugin {
	char *sp_name;
	struct ocfs2_stack_operations *sp_ops;
	struct module *sp_owner;

	/* These are managed by the stackglue code. */
	struct list_head sp_list;
	unsigned int sp_count;
	struct ocfs2_locking_protocol *sp_proto;
};


/* Used by the filesystem */
212 213 214 215 216 217
int ocfs2_cluster_connect(const char *group,
			  int grouplen,
			  void (*recovery_handler)(int node_num,
						   void *recovery_data),
			  void *recovery_data,
			  struct ocfs2_cluster_connection **conn);
218 219
int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
			     int hangup_pending);
220
void ocfs2_cluster_hangup(const char *group, int grouplen);
221
int ocfs2_cluster_this_node(unsigned int *node);
222 223

int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
224
		   int mode,
225
		   union ocfs2_dlm_lksb *lksb,
226 227 228 229
		   u32 flags,
		   void *name,
		   unsigned int namelen,
		   void *astarg);
230
int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
231
		     union ocfs2_dlm_lksb *lksb,
232 233 234
		     u32 flags,
		     void *astarg);

235 236
int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb);
void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb);
237
void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb);
238

239
void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto);
240

241 242 243 244

/* Used by stack plugins */
int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin);
void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin);
245
#endif  /* STACKGLUE_H */