Commit e5a9e8e6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  ocfs2: Negotiate locking protocol versions.
parents bfa271d0 d24fbcda
...@@ -38,6 +38,15 @@ ...@@ -38,6 +38,15 @@
* locking semantics of the file system using the protocol. It should * locking semantics of the file system using the protocol. It should
* be somewhere else, I'm sure, but right now it isn't. * be somewhere else, I'm sure, but right now it isn't.
* *
* With version 11, we separate out the filesystem locking portion. The
* filesystem now has a major.minor version it negotiates. Version 11
* introduces this negotiation to the o2dlm protocol, and as such the
* version here in tcp_internal.h should not need to be bumped for
* filesystem locking changes.
*
* New in version 11
* - Negotiation of filesystem locking in the dlm join.
*
* New in version 10: * New in version 10:
* - Meta/data locks combined * - Meta/data locks combined
* *
...@@ -66,7 +75,7 @@ ...@@ -66,7 +75,7 @@
* - full 64 bit i_size in the metadata lock lvbs * - full 64 bit i_size in the metadata lock lvbs
* - introduction of "rw" lock and pushing meta/data locking down * - introduction of "rw" lock and pushing meta/data locking down
*/ */
#define O2NET_PROTOCOL_VERSION 10ULL #define O2NET_PROTOCOL_VERSION 11ULL
struct o2net_handshake { struct o2net_handshake {
__be64 protocol_version; __be64 protocol_version;
__be64 connector_id; __be64 connector_id;
......
...@@ -193,7 +193,12 @@ enum dlm_status dlmunlock(struct dlm_ctxt *dlm, ...@@ -193,7 +193,12 @@ enum dlm_status dlmunlock(struct dlm_ctxt *dlm,
dlm_astunlockfunc_t *unlockast, dlm_astunlockfunc_t *unlockast,
void *data); void *data);
struct dlm_ctxt * dlm_register_domain(const char *domain, u32 key); struct dlm_protocol_version {
u8 pv_major;
u8 pv_minor;
};
struct dlm_ctxt * dlm_register_domain(const char *domain, u32 key,
struct dlm_protocol_version *fs_proto);
void dlm_unregister_domain(struct dlm_ctxt *dlm); void dlm_unregister_domain(struct dlm_ctxt *dlm);
......
...@@ -142,6 +142,12 @@ struct dlm_ctxt ...@@ -142,6 +142,12 @@ struct dlm_ctxt
spinlock_t work_lock; spinlock_t work_lock;
struct list_head dlm_domain_handlers; struct list_head dlm_domain_handlers;
struct list_head dlm_eviction_callbacks; struct list_head dlm_eviction_callbacks;
/* The filesystem specifies this at domain registration. We
* cache it here to know what to tell other nodes. */
struct dlm_protocol_version fs_locking_proto;
/* This is the inter-dlm communication version */
struct dlm_protocol_version dlm_locking_proto;
}; };
static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned i) static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned i)
...@@ -589,10 +595,24 @@ struct dlm_proxy_ast ...@@ -589,10 +595,24 @@ struct dlm_proxy_ast
#define DLM_PROXY_AST_MAX_LEN (sizeof(struct dlm_proxy_ast)+DLM_LVB_LEN) #define DLM_PROXY_AST_MAX_LEN (sizeof(struct dlm_proxy_ast)+DLM_LVB_LEN)
#define DLM_MOD_KEY (0x666c6172) #define DLM_MOD_KEY (0x666c6172)
enum dlm_query_join_response { enum dlm_query_join_response_code {
JOIN_DISALLOW = 0, JOIN_DISALLOW = 0,
JOIN_OK, JOIN_OK,
JOIN_OK_NO_MAP, JOIN_OK_NO_MAP,
JOIN_PROTOCOL_MISMATCH,
};
union dlm_query_join_response {
u32 intval;
struct {
u8 code; /* Response code. dlm_minor and fs_minor
are only valid if this is JOIN_OK */
u8 dlm_minor; /* The minor version of the protocol the
dlm is speaking. */
u8 fs_minor; /* The minor version of the protocol the
filesystem is speaking. */
u8 reserved;
} packet;
}; };
struct dlm_lock_request struct dlm_lock_request
...@@ -633,6 +653,8 @@ struct dlm_query_join_request ...@@ -633,6 +653,8 @@ struct dlm_query_join_request
u8 node_idx; u8 node_idx;
u8 pad1[2]; u8 pad1[2];
u8 name_len; u8 name_len;
struct dlm_protocol_version dlm_proto;
struct dlm_protocol_version fs_proto;
u8 domain[O2NM_MAX_NAME_LEN]; u8 domain[O2NM_MAX_NAME_LEN];
u8 node_map[BITS_TO_BYTES(O2NM_MAX_NODES)]; u8 node_map[BITS_TO_BYTES(O2NM_MAX_NODES)];
}; };
......
This diff is collapsed.
...@@ -60,6 +60,8 @@ ...@@ -60,6 +60,8 @@
#define MLOG_MASK_PREFIX ML_DLMFS #define MLOG_MASK_PREFIX ML_DLMFS
#include "cluster/masklog.h" #include "cluster/masklog.h"
#include "ocfs2_lockingver.h"
static const struct super_operations dlmfs_ops; static const struct super_operations dlmfs_ops;
static const struct file_operations dlmfs_file_operations; static const struct file_operations dlmfs_file_operations;
static const struct inode_operations dlmfs_dir_inode_operations; static const struct inode_operations dlmfs_dir_inode_operations;
...@@ -69,6 +71,16 @@ static struct kmem_cache *dlmfs_inode_cache; ...@@ -69,6 +71,16 @@ static struct kmem_cache *dlmfs_inode_cache;
struct workqueue_struct *user_dlm_worker; struct workqueue_struct *user_dlm_worker;
/*
* This is the userdlmfs locking protocol version.
*
* See fs/ocfs2/dlmglue.c for more details on locking versions.
*/
static const struct dlm_protocol_version user_locking_protocol = {
.pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
.pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
};
/* /*
* decodes a set of open flags into a valid lock level and a set of flags. * decodes a set of open flags into a valid lock level and a set of flags.
* returns < 0 if we have invalid flags * returns < 0 if we have invalid flags
...@@ -416,6 +428,7 @@ static int dlmfs_mkdir(struct inode * dir, ...@@ -416,6 +428,7 @@ static int dlmfs_mkdir(struct inode * dir,
struct qstr *domain = &dentry->d_name; struct qstr *domain = &dentry->d_name;
struct dlmfs_inode_private *ip; struct dlmfs_inode_private *ip;
struct dlm_ctxt *dlm; struct dlm_ctxt *dlm;
struct dlm_protocol_version proto = user_locking_protocol;
mlog(0, "mkdir %.*s\n", domain->len, domain->name); mlog(0, "mkdir %.*s\n", domain->len, domain->name);
...@@ -435,7 +448,7 @@ static int dlmfs_mkdir(struct inode * dir, ...@@ -435,7 +448,7 @@ static int dlmfs_mkdir(struct inode * dir,
ip = DLMFS_I(inode); ip = DLMFS_I(inode);
dlm = user_dlm_register_context(domain); dlm = user_dlm_register_context(domain, &proto);
if (IS_ERR(dlm)) { if (IS_ERR(dlm)) {
status = PTR_ERR(dlm); status = PTR_ERR(dlm);
mlog(ML_ERROR, "Error %d could not register domain \"%.*s\"\n", mlog(ML_ERROR, "Error %d could not register domain \"%.*s\"\n",
......
...@@ -645,7 +645,8 @@ int user_dlm_destroy_lock(struct user_lock_res *lockres) ...@@ -645,7 +645,8 @@ int user_dlm_destroy_lock(struct user_lock_res *lockres)
return status; return status;
} }
struct dlm_ctxt *user_dlm_register_context(struct qstr *name) struct dlm_ctxt *user_dlm_register_context(struct qstr *name,
struct dlm_protocol_version *proto)
{ {
struct dlm_ctxt *dlm; struct dlm_ctxt *dlm;
u32 dlm_key; u32 dlm_key;
...@@ -661,7 +662,7 @@ struct dlm_ctxt *user_dlm_register_context(struct qstr *name) ...@@ -661,7 +662,7 @@ struct dlm_ctxt *user_dlm_register_context(struct qstr *name)
snprintf(domain, name->len + 1, "%.*s", name->len, name->name); snprintf(domain, name->len + 1, "%.*s", name->len, name->name);
dlm = dlm_register_domain(domain, dlm_key); dlm = dlm_register_domain(domain, dlm_key, proto);
if (IS_ERR(dlm)) if (IS_ERR(dlm))
mlog_errno(PTR_ERR(dlm)); mlog_errno(PTR_ERR(dlm));
......
...@@ -83,7 +83,8 @@ void user_dlm_write_lvb(struct inode *inode, ...@@ -83,7 +83,8 @@ void user_dlm_write_lvb(struct inode *inode,
void user_dlm_read_lvb(struct inode *inode, void user_dlm_read_lvb(struct inode *inode,
char *val, char *val,
unsigned int len); unsigned int len);
struct dlm_ctxt *user_dlm_register_context(struct qstr *name); struct dlm_ctxt *user_dlm_register_context(struct qstr *name,
struct dlm_protocol_version *proto);
void user_dlm_unregister_context(struct dlm_ctxt *dlm); void user_dlm_unregister_context(struct dlm_ctxt *dlm);
struct dlmfs_inode_private { struct dlmfs_inode_private {
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <cluster/masklog.h> #include <cluster/masklog.h>
#include "ocfs2.h" #include "ocfs2.h"
#include "ocfs2_lockingver.h"
#include "alloc.h" #include "alloc.h"
#include "dcache.h" #include "dcache.h"
...@@ -258,6 +259,31 @@ static struct ocfs2_lock_res_ops ocfs2_flock_lops = { ...@@ -258,6 +259,31 @@ static struct ocfs2_lock_res_ops ocfs2_flock_lops = {
.flags = 0, .flags = 0,
}; };
/*
* This is the filesystem locking protocol version.
*
* Whenever the filesystem does new things with locks (adds or removes a
* lock, orders them differently, does different things underneath a lock),
* the version must be changed. The protocol is negotiated when joining
* the dlm domain. A node may join the domain if its major version is
* identical to all other nodes and its minor version is greater than
* or equal to all other nodes. When its minor version is greater than
* the other nodes, it will run at the minor version specified by the
* other nodes.
*
* If a locking change is made that will not be compatible with older
* versions, the major number must be increased and the minor version set
* to zero. If a change merely adds a behavior that can be disabled when
* speaking to older versions, the minor version must be increased. If a
* change adds a fully backwards compatible change (eg, LVB changes that
* are just ignored by older versions), the version does not need to be
* updated.
*/
const struct dlm_protocol_version ocfs2_locking_protocol = {
.pv_major = OCFS2_LOCKING_PROTOCOL_MAJOR,
.pv_minor = OCFS2_LOCKING_PROTOCOL_MINOR,
};
static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
{ {
return lockres->l_type == OCFS2_LOCK_TYPE_META || return lockres->l_type == OCFS2_LOCK_TYPE_META ||
...@@ -2506,7 +2532,8 @@ int ocfs2_dlm_init(struct ocfs2_super *osb) ...@@ -2506,7 +2532,8 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
dlm_key = crc32_le(0, osb->uuid_str, strlen(osb->uuid_str)); dlm_key = crc32_le(0, osb->uuid_str, strlen(osb->uuid_str));
/* for now, uuid == domain */ /* for now, uuid == domain */
dlm = dlm_register_domain(osb->uuid_str, dlm_key); dlm = dlm_register_domain(osb->uuid_str, dlm_key,
&osb->osb_locking_proto);
if (IS_ERR(dlm)) { if (IS_ERR(dlm)) {
status = PTR_ERR(dlm); status = PTR_ERR(dlm);
mlog_errno(status); mlog_errno(status);
......
...@@ -116,4 +116,5 @@ void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb); ...@@ -116,4 +116,5 @@ void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb);
struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void); struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void);
void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug); void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug);
extern const struct dlm_protocol_version ocfs2_locking_protocol;
#endif /* DLMGLUE_H */ #endif /* DLMGLUE_H */
...@@ -251,6 +251,7 @@ struct ocfs2_super ...@@ -251,6 +251,7 @@ struct ocfs2_super
struct ocfs2_lock_res osb_rename_lockres; struct ocfs2_lock_res osb_rename_lockres;
struct dlm_eviction_cb osb_eviction_cb; struct dlm_eviction_cb osb_eviction_cb;
struct ocfs2_dlm_debug *osb_dlm_debug; struct ocfs2_dlm_debug *osb_dlm_debug;
struct dlm_protocol_version osb_locking_proto;
struct dentry *osb_debug_root; struct dentry *osb_debug_root;
......
/* -*- mode: c; c-basic-offset: 8; -*-
* vim: noexpandtab sw=8 ts=8 sts=0:
*
* ocfs2_lockingver.h
*
* Defines OCFS2 Locking version values.
*
* Copyright (C) 2008 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, version 2, as published by the Free Software Foundation.
*
* 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 OCFS2_LOCKINGVER_H
#define OCFS2_LOCKINGVER_H
/*
* The protocol version for ocfs2 cluster locking. See dlmglue.c for
* more details.
*/
#define OCFS2_LOCKING_PROTOCOL_MAJOR 1
#define OCFS2_LOCKING_PROTOCOL_MINOR 0
#endif /* OCFS2_LOCKINGVER_H */
...@@ -1355,6 +1355,7 @@ static int ocfs2_initialize_super(struct super_block *sb, ...@@ -1355,6 +1355,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
sb->s_fs_info = osb; sb->s_fs_info = osb;
sb->s_op = &ocfs2_sops; sb->s_op = &ocfs2_sops;
sb->s_export_op = &ocfs2_export_ops; sb->s_export_op = &ocfs2_export_ops;
osb->osb_locking_proto = ocfs2_locking_protocol;
sb->s_time_gran = 1; sb->s_time_gran = 1;
sb->s_flags |= MS_NOATIME; sb->s_flags |= MS_NOATIME;
/* this is needed to support O_LARGEFILE */ /* this is needed to support O_LARGEFILE */
......
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