/* -*- mode: c; c-basic-offset: 8; -*- * vim: noexpandtab sw=8 ts=8 sts=0: * * stackglue.c * * Code which implements an OCFS2 specific interface to underlying * cluster stacks. * * 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. */ #include #include /* Needed for AOP_TRUNCATED_PAGE in mlog_errno() */ #include #include "cluster/masklog.h" #include "stackglue.h" struct ocfs2_locking_protocol *stack_glue_lproto; int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn, int mode, union ocfs2_dlm_lksb *lksb, u32 flags, void *name, unsigned int namelen, void *astarg) { BUG_ON(stack_glue_lproto == NULL); return o2cb_stack_ops.dlm_lock(conn, mode, lksb, flags, name, namelen, astarg); } int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn, union ocfs2_dlm_lksb *lksb, u32 flags, void *astarg) { BUG_ON(stack_glue_lproto == NULL); return o2cb_stack_ops.dlm_unlock(conn, lksb, flags, astarg); } int ocfs2_dlm_lock_status(union ocfs2_dlm_lksb *lksb) { return o2cb_stack_ops.lock_status(lksb); } /* * Why don't we cast to ocfs2_meta_lvb? The "clean" answer is that we * don't cast at the glue level. The real answer is that the header * ordering is nigh impossible. */ void *ocfs2_dlm_lvb(union ocfs2_dlm_lksb *lksb) { return o2cb_stack_ops.lock_lvb(lksb); } void ocfs2_dlm_dump_lksb(union ocfs2_dlm_lksb *lksb) { o2cb_stack_ops.dump_lksb(lksb); } 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) { int rc = 0; struct ocfs2_cluster_connection *new_conn; BUG_ON(group == NULL); BUG_ON(conn == NULL); BUG_ON(recovery_handler == NULL); if (grouplen > GROUP_NAME_MAX) { rc = -EINVAL; goto out; } new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection), GFP_KERNEL); if (!new_conn) { rc = -ENOMEM; goto out; } memcpy(new_conn->cc_name, group, grouplen); new_conn->cc_namelen = grouplen; new_conn->cc_recovery_handler = recovery_handler; new_conn->cc_recovery_data = recovery_data; /* Start the new connection at our maximum compatibility level */ new_conn->cc_version = stack_glue_lproto->lp_max_version; rc = o2cb_stack_ops.connect(new_conn); if (rc) { mlog_errno(rc); goto out_free; } *conn = new_conn; out_free: if (rc) kfree(new_conn); out: return rc; } int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn) { int ret; BUG_ON(conn == NULL); ret = o2cb_stack_ops.disconnect(conn); /* XXX Should we free it anyway? */ if (!ret) kfree(conn); return ret; } void ocfs2_cluster_hangup(const char *group, int grouplen) { BUG_ON(group == NULL); BUG_ON(group[grouplen] != '\0'); o2cb_stack_ops.hangup(group, grouplen); } int ocfs2_cluster_this_node(unsigned int *node) { return o2cb_stack_ops.this_node(node); } void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto) { BUG_ON(proto != NULL); stack_glue_lproto = proto; }