Commit 41503630 authored by Goldwyn Rodrigues's avatar Goldwyn Rodrigues Committed by Linus Torvalds

ocfs2: framework for version LVB

Use the native DLM locks for version control negotiation.  Most of the
framework is taken from gfs2/lock_dlm.c
Signed-off-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: default avatarMark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3e834151
......@@ -102,6 +102,7 @@
#define OCFS2_TEXT_UUID_LEN 32
#define OCFS2_CONTROL_MESSAGE_VERNUM_LEN 2
#define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8
#define VERSION_LOCK "version_lock"
enum ocfs2_connection_type {
WITH_CONTROLD,
......@@ -118,6 +119,9 @@ struct ocfs2_live_connection {
enum ocfs2_connection_type oc_type;
atomic_t oc_this_node;
int oc_our_slot;
struct dlm_lksb oc_version_lksb;
char oc_lvb[DLM_LVB_LEN];
struct completion oc_sync_wait;
};
struct ocfs2_control_private {
......@@ -796,6 +800,103 @@ static int fs_protocol_compare(struct ocfs2_protocol_version *existing,
return 0;
}
static void lvb_to_version(char *lvb, struct ocfs2_protocol_version *ver)
{
struct ocfs2_protocol_version *pv =
(struct ocfs2_protocol_version *)lvb;
/*
* ocfs2_protocol_version has two u8 variables, so we don't
* need any endian conversion.
*/
ver->pv_major = pv->pv_major;
ver->pv_minor = pv->pv_minor;
}
static void version_to_lvb(struct ocfs2_protocol_version *ver, char *lvb)
{
struct ocfs2_protocol_version *pv =
(struct ocfs2_protocol_version *)lvb;
/*
* ocfs2_protocol_version has two u8 variables, so we don't
* need any endian conversion.
*/
pv->pv_major = ver->pv_major;
pv->pv_minor = ver->pv_minor;
}
static void sync_wait_cb(void *arg)
{
struct ocfs2_cluster_connection *conn = arg;
struct ocfs2_live_connection *lc = conn->cc_private;
complete(&lc->oc_sync_wait);
}
static int sync_unlock(struct ocfs2_cluster_connection *conn,
struct dlm_lksb *lksb, char *name)
{
int error;
struct ocfs2_live_connection *lc = conn->cc_private;
error = dlm_unlock(conn->cc_lockspace, lksb->sb_lkid, 0, lksb, conn);
if (error) {
printk(KERN_ERR "%s lkid %x error %d\n",
name, lksb->sb_lkid, error);
return error;
}
wait_for_completion(&lc->oc_sync_wait);
if (lksb->sb_status != -DLM_EUNLOCK) {
printk(KERN_ERR "%s lkid %x status %d\n",
name, lksb->sb_lkid, lksb->sb_status);
return -1;
}
return 0;
}
static int sync_lock(struct ocfs2_cluster_connection *conn,
int mode, uint32_t flags,
struct dlm_lksb *lksb, char *name)
{
int error, status;
struct ocfs2_live_connection *lc = conn->cc_private;
error = dlm_lock(conn->cc_lockspace, mode, lksb, flags,
name, strlen(name),
0, sync_wait_cb, conn, NULL);
if (error) {
printk(KERN_ERR "%s lkid %x flags %x mode %d error %d\n",
name, lksb->sb_lkid, flags, mode, error);
return error;
}
wait_for_completion(&lc->oc_sync_wait);
status = lksb->sb_status;
if (status && status != -EAGAIN) {
printk(KERN_ERR "%s lkid %x flags %x mode %d status %d\n",
name, lksb->sb_lkid, flags, mode, status);
}
return status;
}
static int version_lock(struct ocfs2_cluster_connection *conn, int mode,
int flags)
{
struct ocfs2_live_connection *lc = conn->cc_private;
return sync_lock(conn, mode, flags,
&lc->oc_version_lksb, VERSION_LOCK);
}
static int version_unlock(struct ocfs2_cluster_connection *conn)
{
struct ocfs2_live_connection *lc = conn->cc_private;
return sync_unlock(conn, &lc->oc_version_lksb, VERSION_LOCK);
}
static void user_recover_prep(void *arg)
{
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment