mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
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: Goldwyn Rodrigues <rgoldwyn@suse.com> Reviewed-by: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
3e83415164
commit
4150363033
1 changed files with 101 additions and 0 deletions
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue