linux/fs/ocfs2/stackglue.h
<<
>>
Prefs
   1/* -*- mode: c; c-basic-offset: 8; -*-
   2 * vim: noexpandtab sw=8 ts=8 sts=0:
   3 *
   4 * stackglue.h
   5 *
   6 * Glue to the underlying cluster stack.
   7 *
   8 * Copyright (C) 2007 Oracle.  All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public
  12 * License as published by the Free Software Foundation, version 2.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 */
  19
  20
  21#ifndef STACKGLUE_H
  22#define STACKGLUE_H
  23
  24#include <linux/types.h>
  25#include <linux/list.h>
  26#include <linux/dlmconstants.h>
  27
  28#include "dlm/dlmapi.h"
  29#include <linux/dlm.h>
  30
  31/* Needed for plock-related prototypes */
  32struct file;
  33struct file_lock;
  34
  35/*
  36 * dlmconstants.h does not have a LOCAL flag.  We hope to remove it
  37 * some day, but right now we need it.  Let's fake it.  This value is larger
  38 * than any flag in dlmconstants.h.
  39 */
  40#define DLM_LKF_LOCAL           0x00100000
  41
  42/*
  43 * This shadows DLM_LOCKSPACE_LEN in fs/dlm/dlm_internal.h.  That probably
  44 * wants to be in a public header.
  45 */
  46#define GROUP_NAME_MAX          64
  47
  48
  49/*
  50 * ocfs2_protocol_version changes when ocfs2 does something different in
  51 * its inter-node behavior.  See dlmglue.c for more information.
  52 */
  53struct ocfs2_protocol_version {
  54        u8 pv_major;
  55        u8 pv_minor;
  56};
  57
  58/*
  59 * The ocfs2_locking_protocol defines the handlers called on ocfs2's behalf.
  60 */
  61struct ocfs2_locking_protocol {
  62        struct ocfs2_protocol_version lp_max_version;
  63        void (*lp_lock_ast)(void *astarg);
  64        void (*lp_blocking_ast)(void *astarg, int level);
  65        void (*lp_unlock_ast)(void *astarg, int error);
  66};
  67
  68
  69/*
  70 * The dlm_lockstatus struct includes lvb space, but the dlm_lksb struct only
  71 * has a pointer to separately allocated lvb space.  This struct exists only to
  72 * include in the lksb union to make space for a combined dlm_lksb and lvb.
  73 */
  74struct fsdlm_lksb_plus_lvb {
  75        struct dlm_lksb lksb;
  76        char lvb[DLM_LVB_LEN];
  77};
  78
  79/*
  80 * A union of all lock status structures.  We define it here so that the
  81 * size of the union is known.  Lock status structures are embedded in
  82 * ocfs2 inodes.
  83 */
  84union ocfs2_dlm_lksb {
  85        struct dlm_lockstatus lksb_o2dlm;
  86        struct dlm_lksb lksb_fsdlm;
  87        struct fsdlm_lksb_plus_lvb padding;
  88};
  89
  90/*
  91 * A cluster connection.  Mostly opaque to ocfs2, the connection holds
  92 * state for the underlying stack.  ocfs2 does use cc_version to determine
  93 * locking compatibility.
  94 */
  95struct ocfs2_cluster_connection {
  96        char cc_name[GROUP_NAME_MAX];
  97        int cc_namelen;
  98        struct ocfs2_protocol_version cc_version;
  99        void (*cc_recovery_handler)(int node_num, void *recovery_data);
 100        void *cc_recovery_data;
 101        void *cc_lockspace;
 102        void *cc_private;
 103};
 104
 105/*
 106 * Each cluster stack implements the stack operations structure.  Not used
 107 * in the ocfs2 code, the stackglue code translates generic cluster calls
 108 * into stack operations.
 109 */
 110struct ocfs2_stack_operations {
 111        /*
 112         * The fs code calls ocfs2_cluster_connect() to attach a new
 113         * filesystem to the cluster stack.  The ->connect() op is passed
 114         * an ocfs2_cluster_connection with the name and recovery field
 115         * filled in.
 116         *
 117         * The stack must set up any notification mechanisms and create
 118         * the filesystem lockspace in the DLM.  The lockspace should be
 119         * stored on cc_lockspace.  Any other information can be stored on
 120         * cc_private.
 121         *
 122         * ->connect() must not return until it is guaranteed that
 123         *
 124         *  - Node down notifications for the filesystem will be recieved
 125         *    and passed to conn->cc_recovery_handler().
 126         *  - Locking requests for the filesystem will be processed.
 127         */
 128        int (*connect)(struct ocfs2_cluster_connection *conn);
 129
 130        /*
 131         * The fs code calls ocfs2_cluster_disconnect() when a filesystem
 132         * no longer needs cluster services.  All DLM locks have been
 133         * dropped, and recovery notification is being ignored by the
 134         * fs code.  The stack must disengage from the DLM and discontinue
 135         * recovery notification.
 136         *
 137         * Once ->disconnect() has returned, the connection structure will
 138         * be freed.  Thus, a stack must not return from ->disconnect()
 139         * until it will no longer reference the conn pointer.
 140         *
 141         * Once this call returns, the stack glue will be dropping this
 142         * connection's reference on the module.
 143         */
 144        int (*disconnect)(struct ocfs2_cluster_connection *conn);
 145
 146        /*
 147         * ->this_node() returns the cluster's unique identifier for the
 148         * local node.
 149         */
 150        int (*this_node)(unsigned int *node);
 151
 152        /*
 153         * Call the underlying dlm lock function.  The ->dlm_lock()
 154         * callback should convert the flags and mode as appropriate.
 155         *
 156         * ast and bast functions are not part of the call because the
 157         * stack will likely want to wrap ast and bast calls before passing
 158         * them to stack->sp_proto.
 159         */
 160        int (*dlm_lock)(struct ocfs2_cluster_connection *conn,
 161                        int mode,
 162                        union ocfs2_dlm_lksb *lksb,
 163                        u32 flags,
 164                        void *name,
 165                        unsigned int namelen,
 166                        void *astarg);
 167
 168        /*
 169         * Call the underlying dlm unlock function.  The ->dlm_unlock()
 170         * function should convert the flags as appropriate.
 171         *
 172         * The unlock ast is not passed, as the stack will want to wrap
 173         * it before calling stack->sp_proto->lp_unlock_ast().
 174         */
 175        int (*dlm_unlock)(struct ocfs2_cluster_connection *conn,
 176                          union ocfs2_dlm_lksb *lksb,
 177                          u32 flags,
 178                          void *astarg);
 179
 180        /*
 181         * Return the status of the current lock status block.  The fs
 182         * code should never dereference the union.  The ->lock_status()
 183         * callback pulls out the stack-specific lksb, converts the status
 184         * to a proper errno, and returns it.
 185         */
 186        int (*lock_status)(union ocfs2_dlm_lksb *lksb);
 187
 188        /*
 189         * Return non-zero if the LVB is valid.
 190         */
 191        int (*lvb_valid)(union ocfs2_dlm_lksb *lksb);
 192
 193        /*
 194         * Pull the lvb pointer off of the stack-specific lksb.
 195         */
 196        void *(*lock_lvb)(union ocfs2_dlm_lksb *lksb);
 197
 198        /*
 199         * Cluster-aware posix locks
 200         *
 201         * This is NULL for stacks which do not support posix locks.
 202         */
 203        int (*plock)(struct ocfs2_cluster_connection *conn,
 204                     u64 ino,
 205                     struct file *file,
 206                     int cmd,
 207                     struct file_lock *fl);
 208
 209        /*
 210         * This is an optoinal debugging hook.  If provided, the
 211         * stack can dump debugging information about this lock.
 212         */
 213        void (*dump_lksb)(union ocfs2_dlm_lksb *lksb);
 214};
 215
 216/*
 217 * Each stack plugin must describe itself by registering a
 218 * ocfs2_stack_plugin structure.  This is only seen by stackglue and the
 219 * stack driver.
 220 */
 221struct ocfs2_stack_plugin {
 222        char *sp_name;
 223        struct ocfs2_stack_operations *sp_ops;
 224        struct module *sp_owner;
 225
 226        /* These are managed by the stackglue code. */
 227        struct list_head sp_list;
 228        unsigned int sp_count;
 229        struct ocfs2_locking_protocol *sp_proto;
 230};
 231
 232
 233/* Used by the filesystem */
 234int ocfs2_cluster_connect(const char *stack_name,
 235                          const char *group,
 236                          int grouplen,
 237                          void (*recovery_handler)(int node_num,
 238                                                   void *recovery_data),
 239                          void *recovery_data,
 240                          struct ocfs2_cluster_connection **conn);
 241int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
 242                             int hangup_pending);
 243void ocfs2_cluster_hangup(const char *group, int grouplen);
 244int ocfs2_cluster_this_node(unsigned int *node);
 245
 246struct ocfs2_lock_res;
 247int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
 248                   int mode,
 249                   union ocfs2_dlm_lksb *lksb,
 250                   u32 flags,
 251                   void *name,
 252                   unsigned int namelen,
 253                   struct ocfs2_lock_res *astarg);
 254int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
 255                     union ocfs2_dlm_lksb *lksb,
 256                     u32 flags,
 257                     struct ocfs2_lock_res *astarg);
 258
 259int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb);
 260int ocfs2_dlm_lvb_valid(union ocfs2_dlm_lksb *lksb);
 261void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb);
 262void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb);
 263
 264int ocfs2_stack_supports_plocks(void);
 265int ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino,
 266                struct file *file, int cmd, struct file_lock *fl);
 267
 268void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto);
 269
 270
 271/* Used by stack plugins */
 272int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin);
 273void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin);
 274
 275#endif  /* STACKGLUE_H */
 276