[Ocfs2-commits] mfasheh commits r1900 - trunk/fs/ocfs2/dlm
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Feb 22 15:22:28 CST 2005
Author: mfasheh
Signed-off-by: zab
Date: 2005-02-22 15:22:26 -0600 (Tue, 22 Feb 2005)
New Revision: 1900
Modified:
trunk/fs/ocfs2/dlm/dlmast.c
trunk/fs/ocfs2/dlm/dlmconvert.c
trunk/fs/ocfs2/dlm/dlmlock.c
trunk/fs/ocfs2/dlm/dlmmaster.c
trunk/fs/ocfs2/dlm/dlmmod.c
trunk/fs/ocfs2/dlm/dlmmod.h
trunk/fs/ocfs2/dlm/dlmunlock.c
Log:
* change module author line to proper name
* clean up some needless indents
* implement some api cleanups and basic ref counting hooks. we will actually
start using these in a future commit.
- this fixes at least one memory leak in the lockres hashing code
- we now only kmalloc when actually required, rather than on every non
converting call to dlmlock.
* add some limits checking to network handlers
Signed-off-by: zab
Modified: trunk/fs/ocfs2/dlm/dlmast.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmast.c 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmast.c 2005-02-22 21:22:26 UTC (rev 1900)
@@ -128,13 +128,13 @@
int dlm_proxy_ast_handler(net_msg *msg, u32 len, void *data)
{
- int ret;
- int status;
+ int ret, status;
+ unsigned int locklen;
dlm_ctxt *dlm = data;
- dlm_lock_resource *res;
+ dlm_lock_resource *res = NULL;
dlm_lock *lock = NULL;
dlm_proxy_ast *past = (dlm_proxy_ast *) msg->buf;
- struct qstr lockname;
+ char *name;
struct list_head *iter, *head=NULL;
u64 cookie;
u32 flags;
@@ -143,11 +143,17 @@
return DLM_REJECTED;
dlm_proxy_ast_to_host(past);
- lockname.name = past->name;
- lockname.len = past->namelen;
+ name = past->name;
+ locklen = past->namelen;
cookie = past->cookie;
flags = past->flags;
+ if (locklen > DLM_LOCKID_NAME_MAX) {
+ ret = DLM_IVBUFLEN;
+ printk("Invalid name length in proxy ast handler!\n");
+ goto leave;
+ }
+
if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
(LKM_PUT_LVB|LKM_GET_LVB)) {
dlmprintk("both PUT and GET lvb specified\n");
@@ -158,25 +164,23 @@
dlmprintk("lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" :
(flags & LKM_GET_LVB ? "get lvb" : "none"));
- lockname.hash = full_name_hash(lockname.name, lockname.len);
-
dlmprintk("type=%d, blocked_type=%d\n", past->type, past->blocked_type);
if (past->type != DLM_AST &&
past->type != DLM_BAST) {
dlmprintk("Eeeek unknown ast type! %d, cookie=%llu, "
"name=%*s\n",
- past->type, cookie, lockname.len, lockname.name);
+ past->type, cookie, locklen, name);
ret = DLM_IVLOCKID;
goto leave;
}
- res = dlm_lookup_lock(dlm, &lockname);
+ res = dlm_lookup_lock(dlm, name, locklen);
if (!res) {
dlmprintk("eek! got %sast for unknown lockres! cookie=%llu, "
- "name=%*s, namelen=%d\n",
+ "name=%*s, namelen=%u\n",
past->type == DLM_AST ? "" : "b",
- cookie, lockname.len, lockname.name, lockname.len);
+ cookie, locklen, name, locklen);
ret = DLM_IVLOCKID;
goto leave;
}
@@ -208,9 +212,9 @@
}
dlmprintk("eek! got %sast for unknown lock! cookie=%llu, "
- "name=%*s, namelen=%d\n",
+ "name=%*s, namelen=%u\n",
past->type == DLM_AST ? "" : "b",
- cookie, lockname.len, lockname.name, lockname.len);
+ cookie, locklen, name, locklen);
spin_unlock(&res->spinlock);
if (!dlm_is_recovery_lock(past->name, past->namelen))
up_read(&dlm->recovery_sem);
@@ -258,6 +262,9 @@
leave:
+ if (res)
+ dlm_lockres_put(dlm, res);
+
dlm_put(dlm);
return ret;
}
@@ -275,7 +282,6 @@
res->lockname.len, res->lockname.name, lock->node,
type, blocked_type);
-
memset(&past, 0, sizeof(dlm_proxy_ast));
past.node_idx = dlm->group_index;
past.type = type;
Modified: trunk/fs/ocfs2/dlm/dlmconvert.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmconvert.c 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmconvert.c 2005-02-22 21:22:26 UTC (rev 1900)
@@ -374,7 +374,6 @@
dlm_lock *lock = NULL;
dlm_lockstatus *lksb;
dlm_status status = DLM_NORMAL;
- struct qstr lockname;
u32 flags;
int call_ast = 0, kick_thread = 0;
int found = 0;
@@ -383,8 +382,12 @@
return DLM_REJECTED;
dlm_convert_lock_to_host(cnv);
- lockname.name = cnv->name;
- lockname.len = cnv->namelen;
+
+ if (cnv->namelen > DLM_LOCKID_NAME_MAX) {
+ status = DLM_IVBUFLEN;
+ goto leave;
+ }
+
flags = cnv->flags;
if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
@@ -396,11 +399,9 @@
dlmprintk("lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" :
(flags & LKM_GET_LVB ? "get lvb" : "none"));
-
- lockname.hash = full_name_hash(lockname.name, lockname.len);
status = DLM_IVLOCKID;
- res = dlm_lookup_lock(dlm, &lockname);
+ res = dlm_lookup_lock(dlm, cnv->name, cnv->namelen);
if (!res)
goto leave;
@@ -451,6 +452,9 @@
if (kick_thread)
dlm_kick_thread(dlm, res);
+ if (res)
+ dlm_lockres_put(dlm, res);
+
dlm_put(dlm);
return status;
Modified: trunk/fs/ocfs2/dlm/dlmlock.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmlock.c 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmlock.c 2005-02-22 21:22:26 UTC (rev 1900)
@@ -240,11 +240,12 @@
{
dlm_ctxt *dlm = data;
dlm_create_lock *create = (dlm_create_lock *)msg->buf;
- dlm_lock_resource *res;
- dlm_lock *newlock;
+ dlm_lock_resource *res = NULL;
+ dlm_lock *newlock = NULL;
dlm_lockstatus *lksb = NULL;
dlm_status status = DLM_NORMAL;
- struct qstr lockname;
+ char *name;
+ unsigned int namelen;
DLM_ASSERT(dlm);
@@ -254,10 +255,12 @@
return DLM_REJECTED;
dlm_create_lock_to_host(create);
- lockname.name = create->name;
- lockname.len = create->namelen;
+ name = create->name;
+ namelen = create->namelen;
- lockname.hash = full_name_hash(lockname.name, lockname.len);
+ status = DLM_IVBUFLEN;
+ if (namelen > DLM_LOCKID_NAME_MAX)
+ goto leave;
status = DLM_SYSERR;
newlock = kmalloc(sizeof(dlm_lock), GFP_KERNEL);
@@ -292,7 +295,7 @@
}
status = DLM_IVLOCKID;
- res = dlm_lookup_lock(dlm, &lockname);
+ res = dlm_lookup_lock(dlm, name, namelen);
if (!res)
goto leave;
@@ -308,6 +311,9 @@
kfree(lksb);
}
+ if (res)
+ dlm_lockres_put(dlm, res);
+
dlm_put(dlm);
return status;
Modified: trunk/fs/ocfs2/dlm/dlmmaster.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmaster.c 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmmaster.c 2005-02-22 21:22:26 UTC (rev 1900)
@@ -56,13 +56,14 @@
/* gives a really vague idea of the system load */
atomic_t dlm_num_resources = ATOMIC_INIT(0);
-
-static int dlm_init_mle(dlm_master_list_entry *mle, enum dlm_mle_type type,
- dlm_ctxt *dlm, dlm_lock_resource *res,
- struct qstr *name, int locked);
+static int dlm_init_mle(dlm_master_list_entry *mle,
+ enum dlm_mle_type type,
+ dlm_ctxt *dlm,
+ dlm_lock_resource *res,
+ const char *name,
+ unsigned int namelen,
+ int locked);
static void dlm_put_mle(dlm_master_list_entry *mle);
-static int dlm_do_master_request_resp(dlm_ctxt *dlm, struct qstr *name,
- int response, int to);
static int dlm_do_master_request(dlm_master_list_entry *mle, int to);
static int dlm_do_assert_master(dlm_master_list_entry *mle);
static void dlm_mle_node_up(struct inode *group, struct inode *node,
@@ -70,9 +71,6 @@
static void dlm_mle_node_down(struct inode *group, struct inode *node,
int idx, void *data);
-
-
-
/* remove from list and free */
static void dlm_put_mle(dlm_master_list_entry *mle)
{
@@ -90,14 +88,16 @@
atomic_inc(&mle->refcnt);
}
-
-
-static int dlm_init_mle(dlm_master_list_entry *mle, enum dlm_mle_type type,
- dlm_ctxt *dlm, dlm_lock_resource *res,
- struct qstr *name, int locked)
+static int dlm_init_mle(dlm_master_list_entry *mle,
+ enum dlm_mle_type type,
+ dlm_ctxt *dlm,
+ dlm_lock_resource *res,
+ const char *name,
+ unsigned int namelen,
+ int locked)
{
int ret = 0;
-
+
mle->dlm = dlm;
mle->type = type;
INIT_LIST_HEAD(&mle->list);
@@ -113,8 +113,8 @@
if (mle->type == DLM_MLE_MASTER)
mle->u.res = res;
else
- strncpy(mle->u.name.name, name->name, name->len);
-
+ strncpy(mle->u.name.name, name, namelen);
+
if (!locked)
spin_lock(&dlm->spinlock);
@@ -139,9 +139,6 @@
return ret;
}
-
-
-
/////////////////////////////////////////////////
//
// TODO: change these comments to reflect reality
@@ -179,12 +176,104 @@
//
/////////////////////////////////////////////////
+static void dlm_lockres_release(struct kref *kref)
+{
+ dlm_lock_resource *res;
+ BUG_ON(!kref);
+ res = container_of(kref, dlm_lock_resource, refs);
+ /* This should not happen -- all lockres' have a name
+ * associated with them at init time. */
+ BUG_ON(!res->lockname.name);
+
+ dlmprintk("destroying lockres %*s\n", res->lockname.len,
+ res->lockname.name);
+
+ /* By the time we're ready to blow this guy away, we shouldn't
+ * be on any lists. */
+ BUG_ON(!list_empty(&res->list));
+ BUG_ON(!list_empty(&res->granted));
+ BUG_ON(!list_empty(&res->converting));
+ BUG_ON(!list_empty(&res->blocked));
+ BUG_ON(!list_empty(&res->dirty));
+ BUG_ON(!list_empty(&res->recovering));
+
+ kfree(res->lockname.name);
+
+ kfree(res);
+}
+
+void __dlm_lockres_get(dlm_lock_resource *res)
+{
+ kref_get(&res->refs);
+}
+
+void dlm_lockres_put(dlm_ctxt *dlm,
+ dlm_lock_resource *res)
+{
+ spin_lock(&dlm->spinlock);
+ kref_put(&res->refs, dlm_lockres_release);
+ spin_unlock(&dlm->spinlock);
+}
+
+static void dlm_init_lockres(dlm_lock_resource *res,
+ const char *name,
+ unsigned int namelen)
+{
+ char *qname;
+
+ /* If we memset here, we lose our reference to the kmalloc'd
+ * res->lockname.name, so be sure to init every field
+ * correctly! */
+
+ qname = (char *) res->lockname.name;
+ strncpy(qname, name, namelen);
+
+ res->lockname.len = namelen;
+ res->lockname.hash = full_name_hash(name, namelen);
+
+ init_waitqueue_head(&res->wq);
+ spin_lock_init(&res->spinlock);
+ INIT_LIST_HEAD(&res->list);
+ INIT_LIST_HEAD(&res->granted);
+ INIT_LIST_HEAD(&res->converting);
+ INIT_LIST_HEAD(&res->blocked);
+ INIT_LIST_HEAD(&res->dirty);
+ INIT_LIST_HEAD(&res->recovering);
+
+ kref_init(&res->refs, dlm_lockres_release);
+
+ res->owner = DLM_LOCK_RES_OWNER_UNKNOWN;
+ res->state = DLM_LOCK_RES_IN_PROGRESS;
+
+ memset(res->lvb, 0, DLM_LVB_LEN);
+}
+
+static dlm_lock_resource *dlm_new_lockres(const char *name,
+ unsigned int namelen)
+{
+ dlm_lock_resource *res;
+
+ res = kmalloc(sizeof(dlm_lock_resource), GFP_KERNEL);
+ if (!res)
+ return NULL;
+
+ res->lockname.name = kmalloc(namelen, GFP_KERNEL);
+ if (!res->lockname.name) {
+ kfree(res);
+ return NULL;
+ }
+
+ dlm_init_lockres(res, name, namelen);
+ return res;
+}
+
/*
* lookup a lock resource by name.
* may already exist in the hashtable.
+ * lockid is null terminated
*
* if not, allocate enough for the lockres and for
* the temporary structure used in doing the mastering.
@@ -198,41 +287,51 @@
*
*/
dlm_lock_resource * dlm_get_lock_resource(dlm_ctxt *dlm,
- struct qstr *lockname, int flags)
+ const char *lockid,
+ int flags)
{
dlm_lock_resource *tmpres=NULL, *res=NULL;
- struct list_head *bucket;
dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
struct list_head *iter;
int blocked = 0;
int map_changed = 0, restart = 0, assert = 0;
int ret, start, bit;
+ unsigned int namelen;
- bucket = &(dlm->resources[lockname->hash & DLM_HASH_MASK]);
+ BUG_ON(!lockid);
+ BUG_ON(!dlm);
+ namelen = strlen(lockid);
+
+ dlmprintk("get lockres %s (len %d)\n", lockid, namelen);
+
lookup:
spin_lock(&dlm->spinlock);
- tmpres = __dlm_lookup_lock(dlm, lockname);
+ tmpres = __dlm_lookup_lock(dlm, lockid, namelen);
if (tmpres) {
spin_unlock(&dlm->spinlock);
+ dlmprintk("found in hash!\n");
+
if (mle)
kfree(mle);
+
if (res)
- kfree(res);
+ dlm_lockres_put(dlm, res);
return tmpres;
}
if (!res) {
spin_unlock(&dlm->spinlock);
+ dlmprintk("allocating a new resource\n");
/* nothing found and we need to allocate one. */
mle = kmalloc(sizeof(dlm_master_list_entry), GFP_KERNEL);
if (!mle)
return NULL;
- res = kmalloc(sizeof(dlm_lock_resource), GFP_KERNEL);
+ res = dlm_new_lockres(lockid, namelen);
if (!res) {
kfree(mle);
return NULL;
@@ -241,13 +340,12 @@
goto lookup;
}
- /* Ok, no lockres found and we have one to insert... */
- dlm_init_lockres(res, lockname);
+ dlmprintk("no lockres found, allocated our own: %p\n", res);
if (flags & LKM_LOCAL) {
/* caller knows it's safe to assume it's not mastered elsewhere
* DONE! return right away */
- list_add_tail(&res->list, bucket);
+ __dlm_insert_lock(dlm, res);
res->owner = dlm->group_index;
atomic_inc(&dlm_num_resources);
spin_unlock(&dlm->spinlock);
@@ -259,7 +357,7 @@
spin_lock(&dlm_master_lock);
list_for_each(iter, &dlm_master_list) {
tmpmle = list_entry(iter, dlm_master_list_entry, list);
- if (!dlm_mle_equal(dlm, tmpmle, lockname))
+ if (!dlm_mle_equal(dlm, tmpmle, lockid, namelen))
continue;
if (tmpmle->type == DLM_MLE_MASTER) {
@@ -275,7 +373,7 @@
if (!blocked) {
/* go ahead and try to master lock on this node */
- if (dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 1)) {
+ if (dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 0, 1)) {
dlmprintk0("bug! failed to register hb callbacks\n");
BUG();
}
@@ -294,7 +392,7 @@
* to come in and put their mle on the list and sleep ?? */
/* finally add the lockres to its hash bucket */
- list_add_tail(&res->list, bucket);
+ __dlm_insert_lock(dlm, res);
atomic_inc(&dlm_num_resources);
spin_unlock(&dlm->spinlock);
@@ -313,7 +411,7 @@
dlmprintk0("no more nodes\n");
break;
}
-
+
ret = dlm_do_master_request(mle, bit);
if (ret < 0) {
// TODO
@@ -389,8 +487,8 @@
* the vote_map, zero everything out
* and start over */
dlmprintk("need to handle this case. "
- "winning node %u just died\n",
- bit);
+ "winning node %u just "
+ "died\n", bit);
restart = 1;
}
@@ -483,9 +581,6 @@
return res;
}
-
-
-
/*
* locks that can be taken here:
* dlm->spinlock
@@ -502,7 +597,8 @@
dlm_lock_resource *res;
dlm_master_request *request = (dlm_master_request *) msg->buf;
dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
- struct qstr lockname;
+ char *name;
+ unsigned int namelen;
int found;
struct list_head *iter;
@@ -510,13 +606,17 @@
return DLM_MASTER_RESP_NO;
dlm_master_request_to_host(request);
- lockname.name = request->name;
- lockname.len = request->namelen;
- lockname.hash = full_name_hash(lockname.name, lockname.len);
+ name = request->name;
+ namelen = request->namelen;
-way_up_top:
+ if (namelen > DLM_LOCKID_NAME_MAX) {
+ response = DLM_IVBUFLEN;
+ goto send_response;
+ }
+
+way_up_top:
spin_lock(&dlm->spinlock);
- res = __dlm_lookup_lock(dlm, &lockname);
+ res = __dlm_lookup_lock(dlm, name, namelen);
if (res) {
spin_unlock(&dlm->spinlock);
@@ -552,7 +652,7 @@
spin_lock(&dlm_master_lock);
list_for_each(iter, &dlm_master_list) {
tmpmle = list_entry(iter, dlm_master_list_entry, list);
- if (!dlm_mle_equal(dlm, tmpmle, &lockname))
+ if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
continue;
dlm_get_mle(tmpmle);
@@ -593,7 +693,7 @@
spin_lock(&dlm_master_lock);
list_for_each(iter, &dlm_master_list) {
tmpmle = list_entry(iter, dlm_master_list_entry, list);
- if (!dlm_mle_equal(dlm, tmpmle, &lockname))
+ if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
continue;
dlm_get_mle(tmpmle);
found = 1;
@@ -608,14 +708,14 @@
spin_unlock(&dlm->spinlock);
mle = kmalloc(sizeof(dlm_master_list_entry) +
- lockname.len, GFP_KERNEL);
+ namelen, GFP_KERNEL);
if (!mle) {
// bad bad bad... this sucks.
response = DLM_MASTER_RESP_ERROR;
goto send_response;
}
if (dlm_init_mle(mle, DLM_MLE_BLOCK, dlm, NULL,
- &lockname, 0)) {
+ name, namelen, 0)) {
dlmprintk0("eeek!\n");
response = DLM_MASTER_RESP_ERROR;
dlm_put_mle(mle);
@@ -645,10 +745,6 @@
send_response:
dlm_put(dlm);
- //ret = dlm_do_master_request_resp(dlm, &lockname, response,
- // request->node_idx);
- //dlmprintk("response returned %d\n", ret);
- //dlmprintk("sending response %d to other node\n", response);
return response;
}
@@ -669,20 +765,21 @@
dlm_master_request_resp *resp = (dlm_master_request_resp *) msg->buf;
int found = 0, wake = 0;
struct list_head *iter;
- struct qstr lockname;
if (!dlm_grab(dlm))
return 0;
dlm_master_request_resp_to_host(resp);
- lockname.name = resp->name;
- lockname.len = resp->namelen;
- lockname.hash = full_name_hash(lockname.name, lockname.len);
+ if (resp->namelen > DLM_LOCKID_NAME_MAX) {
+ printk("Invalid name length in master request response!\n");
+ goto done;
+ }
+
spin_lock(&dlm_master_lock);
list_for_each(iter, &dlm_master_list) {
mle = list_entry(iter, dlm_master_list_entry, list);
- if (!dlm_mle_equal(dlm, mle, &lockname)) {
+ if (!dlm_mle_equal(dlm, mle, resp->name, resp->namelen)) {
mle = NULL;
continue;
}
@@ -746,6 +843,7 @@
dlmprintk0("hrrm... got a master resp but found no matching "
"request\n");
+done:
dlm_put(dlm);
return 0;
}
@@ -767,23 +865,28 @@
dlm_lock_resource *res;
int bit;
struct list_head *iter;
- struct qstr lockname;
+ char *name;
+ unsigned int namelen;
if (!dlm_grab(dlm))
return 0;
dlm_assert_master_to_host(assert);
- lockname.name = assert->name;
- lockname.len = assert->namelen;
- lockname.hash = full_name_hash(lockname.name, lockname.len);
+ name = assert->name;
+ namelen = assert->namelen;
+ if (namelen > DLM_LOCKID_NAME_MAX) {
+ printk("Invalid name length in master assert handler!\n");
+ goto done;
+ }
+
spin_lock(&dlm->spinlock);
/* find the MLE */
spin_lock(&dlm_master_lock);
list_for_each(iter, &dlm_master_list) {
mle = list_entry(iter, dlm_master_list_entry, list);
- if (dlm_mle_equal(dlm, mle, &lockname)) {
+ if (dlm_mle_equal(dlm, mle, name, namelen)) {
dlm_get_mle(mle);
break;
}
@@ -812,7 +915,7 @@
/* ok everything checks out with the MLE
* now check to see if there is a lockres */
check_lockres:
- res = __dlm_lookup_lock(dlm, &lockname);
+ res = __dlm_lookup_lock(dlm, name, namelen);
if (res) {
spin_lock(&res->spinlock);
if (!mle) {
@@ -855,11 +958,11 @@
dlm_put_mle(mle);
}
+done:
dlm_put(dlm);
return 0;
}
-
static int dlm_do_master_request(dlm_master_list_entry *mle, int to)
{
struct inode *inode = NULL;
@@ -928,30 +1031,6 @@
return ret;
}
-static int dlm_do_master_request_resp(dlm_ctxt *dlm, struct qstr *name,
- int response, int to)
-{
- struct inode *inode = NULL;
- dlm_master_request_resp resp;
- int ret;
-
- memset(&resp, 0, sizeof(resp));
- resp.node_idx = dlm->group_index;
- resp.response = response;
- resp.namelen = name->len;
- strncpy(resp.name, name->name, name->len);
-
- inode = nm_get_group_node_by_index(dlm->group, to);
- if (!inode)
- return -EINVAL;
-
- dlm_master_request_resp_to_net(&resp);
- ret = net_send_message(DLM_MASTER_REQUEST_RESP_MSG, dlm->key,
- &resp, sizeof(resp), inode, NULL);
- iput(inode);
- return ret;
-}
-
/*
* NOTE: this can be used for debugging
* can periodically run all locks owned by this node
@@ -1009,11 +1088,6 @@
return ret;
}
-
-
-
-
-
static void dlm_mle_node_down(struct inode *group, struct inode *node,
int idx, void *data)
{
Modified: trunk/fs/ocfs2/dlm/dlmmod.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmod.c 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmmod.c 2005-02-22 21:22:26 UTC (rev 1900)
@@ -51,8 +51,7 @@
#include "dlmmod.h"
MODULE_LICENSE ("GPL");
-MODULE_AUTHOR("Oracle Corporation");
-//MODULE_DESCRIPTION("Oracle DLM");
+MODULE_AUTHOR("Oracle");
/*
@@ -150,18 +149,15 @@
}
spin_unlock(&dlm_cookie_lock);
}
-
dlm_status dlmlock(dlm_ctxt *dlm, int mode, dlm_lockstatus *lksb, int flags,
- char *name, dlm_astlockfunc_t *ast, void *data,
+ const char *name, dlm_astlockfunc_t *ast, void *data,
dlm_bastlockfunc_t *bast)
{
dlm_status status;
dlm_lock_resource *res;
dlm_lock *lock = NULL;
- char *buf = NULL;
int convert = 0, recovery = 0;
- struct qstr q;
if (!lksb)
return DLM_BADARGS;
@@ -192,7 +188,7 @@
if (!lksb->lockid || !lksb->lockid->lockres)
goto error_status;
lock = lksb->lockid;
-
+
/* XXX: for ocfs2 purposes, the ast/bast/astdata/lksb are
* static after the original lock call. convert requests will
* ensure that everything is the same, or return DLM_BADARGS.
@@ -223,32 +219,20 @@
goto error;
status = DLM_IVBUFLEN;
- q.len = strlen(name);
- if (q.len > DLM_LOCKID_NAME_MAX)
+ if (strlen(name) > DLM_LOCKID_NAME_MAX)
goto error;
- /* take care of all allocs before any locking */
- status = DLM_SYSERR;
- buf = kmalloc(q.len+1, GFP_KERNEL); /* lockres name */
- if (!buf)
- goto error;
-
- memcpy(buf, name, q.len);
- buf[q.len] = 0;
- q.name = buf;
- q.hash = full_name_hash(q.name, q.len);
-
lock = kmalloc(sizeof(dlm_lock), GFP_KERNEL); /* dlm_lock */
if (!lock)
goto error;
lksb->lockid = lock;
- if (!recovery)
+ if (!recovery)
down_read(&dlm->recovery_sem);
/* find or create the lock resource */
- res = dlm_get_lock_resource(dlm, &q, flags);
+ res = dlm_get_lock_resource(dlm, name, flags);
if (!res) {
status = DLM_IVLOCKID;
goto up_error;
@@ -305,8 +289,6 @@
if (!recovery)
up_read(&dlm->recovery_sem);
error:
- if (buf)
- kfree(buf);
if (lock && !convert) {
kfree(lock);
lksb->lockid = NULL;
@@ -382,33 +364,63 @@
}
EXPORT_SYMBOL(dlmunlock);
-dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname)
+void __dlm_insert_lock(dlm_ctxt *dlm,
+ dlm_lock_resource *res)
{
+ struct list_head *bucket;
+ struct qstr *q;
+
+ q = &res->lockname;
+ q->hash = full_name_hash(q->name, q->len);
+ bucket = &(dlm->resources[q->hash & DLM_HASH_MASK]);
+
+ /* get a reference for our hashtable */
+ __dlm_lockres_get(res);
+
+ list_add_tail(&res->list, bucket);
+}
+
+dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm,
+ const char *name,
+ unsigned int len)
+{
+ unsigned int hash;
struct list_head *iter;
dlm_lock_resource *tmpres=NULL;
struct list_head *bucket;
+ BUG_ON(!name);
+
dlmprintk0("\n");
- bucket = &(dlm->resources[lockname->hash & DLM_HASH_MASK]);
+ hash = full_name_hash(name, len);
+ bucket = &(dlm->resources[hash & DLM_HASH_MASK]);
+
/* check for pre-existing lock */
list_for_each(iter, bucket) {
tmpres = list_entry(iter, dlm_lock_resource, list);
- if (tmpres->lockname.len == lockname->len &&
- strncmp(tmpres->lockname.name, lockname->name,
- lockname->len) == 0)
+ if (tmpres->lockname.len == len &&
+ strncmp(tmpres->lockname.name, name, len) == 0) {
+ __dlm_lockres_get(tmpres);
break;
+ }
+
tmpres = NULL;
}
return tmpres;
}
-dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname)
+dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm,
+ const char *name,
+ unsigned int len)
{
dlm_lock_resource *res;
+
+ BUG_ON(!dlm);
+
spin_lock(&dlm->spinlock);
- res = __dlm_lookup_lock(dlm, lockname);
+ res = __dlm_lookup_lock(dlm, name, len);
spin_unlock(&dlm->spinlock);
return res;
}
@@ -866,25 +878,6 @@
}
EXPORT_SYMBOL(dlm_register_domain);
-void dlm_init_lockres(dlm_lock_resource *res, struct qstr *lockname)
-{
- memset(res, 0, sizeof(dlm_lock_resource));
- res->lockname.name = lockname->name;
- res->lockname.len = lockname->len;
- res->lockname.hash = lockname->hash;
- init_waitqueue_head(&res->wq);
- spin_lock_init(&res->spinlock);
- INIT_LIST_HEAD(&res->list);
- INIT_LIST_HEAD(&res->granted);
- INIT_LIST_HEAD(&res->converting);
- INIT_LIST_HEAD(&res->blocked);
- INIT_LIST_HEAD(&res->dirty);
- INIT_LIST_HEAD(&res->recovering);
-
- res->owner = DLM_LOCK_RES_OWNER_UNKNOWN;
- res->state |= DLM_LOCK_RES_IN_PROGRESS;
-}
-
/* will exit holding res->spinlock, but may drop in function */
void __dlm_wait_on_lockres(dlm_lock_resource *res)
{
@@ -903,10 +896,6 @@
current->state = TASK_RUNNING;
}
-
-
-
-
void dlm_dump_everything(void)
{
dlm_ctxt *dlm;
Modified: trunk/fs/ocfs2/dlm/dlmmod.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmmod.h 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmmod.h 2005-02-22 21:22:26 UTC (rev 1900)
@@ -117,7 +117,7 @@
#define DLM_RECOVERY_LOCK_NAME "$RECOVERY"
#define DLM_RECOVERY_LOCK_NAME_LEN 9
-static inline int dlm_is_recovery_lock(char *lock_name, int name_len)
+static inline int dlm_is_recovery_lock(const char *lock_name, int name_len)
{
if (name_len == DLM_RECOVERY_LOCK_NAME_LEN &&
strncmp(lock_name, DLM_RECOVERY_LOCK_NAME, DLM_RECOVERY_LOCK_NAME_LEN)==0)
@@ -220,8 +220,11 @@
typedef struct _dlm_lock_resource
{
+ /* WARNING: Please see the comment in dlm_init_lockres before
+ * adding fields here. */
struct list_head list;
-
+ struct kref refs;
+
/* please keep these next 3 in this order
* some funcs want to iterate over all lists */
struct list_head granted;
@@ -232,7 +235,7 @@
struct list_head recovering; // dlm_recovery_ctxt.resources list
spinlock_t spinlock;
wait_queue_head_t wq;
- u8 owner; // node which owns the lock resource, or unknown
+ u8 owner; //node which owns the lock resource, or unknown
u16 state;
struct qstr lockname;
char lvb[DLM_LVB_LEN];
@@ -534,8 +537,14 @@
int dlm_launch_thread(dlm_ctxt *dlm);
void dlm_complete_thread(dlm_ctxt *dlm);
-dlm_status dlmlock(dlm_ctxt *dlm, int mode, dlm_lockstatus *lksb, int flags, char *name,
- dlm_astlockfunc_t *ast, void *data, dlm_bastlockfunc_t *bast);
+dlm_status dlmlock(dlm_ctxt *dlm,
+ int mode,
+ dlm_lockstatus *lksb,
+ int flags,
+ const char *name,
+ dlm_astlockfunc_t *ast,
+ void *data,
+ dlm_bastlockfunc_t *bast);
dlm_status dlmlock_master(dlm_ctxt *dlm, dlm_lock_resource *res,
dlm_lock *lock, int flags);
@@ -574,7 +583,21 @@
void dlm_put(dlm_ctxt *dlm);
dlm_ctxt *dlm_grab(dlm_ctxt *dlm);
-dlm_lock_resource * dlm_get_lock_resource(dlm_ctxt *dlm, struct qstr *lockname, int flags);
+void __dlm_lockres_get(dlm_lock_resource *res);
+void dlm_lockres_put(dlm_ctxt *dlm,
+ dlm_lock_resource *res);
+void __dlm_insert_lock(dlm_ctxt *dlm,
+ dlm_lock_resource *res);
+dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm,
+ const char *name,
+ unsigned int len);
+dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm,
+ const char *name,
+ unsigned int len);
+dlm_lock_resource * dlm_get_lock_resource(dlm_ctxt *dlm,
+ const char *lockid,
+ int flags);
+
int dlm_lock_owner_broadcast(dlm_ctxt *dlm, dlm_lock_resource *res);
int dlm_refresh_lock_resource(dlm_ctxt *dlm, dlm_lock_resource *res);
int dlm_do_ast(dlm_ctxt *dlm, dlm_lock_resource *res, dlm_lock *lock);
@@ -584,9 +607,6 @@
int dlm_nm_init(dlm_ctxt *dlm);
int dlm_heartbeat_init(dlm_ctxt *dlm);
-
-dlm_lock_resource * dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname);
-
void dlm_hb_node_down_cb(struct inode *group, struct inode *node, int idx, void *data);
void dlm_hb_node_up_cb(struct inode *group, struct inode *node, int idx, void *data);
int dlm_hb_node_dead(dlm_ctxt *dlm, int node);
@@ -598,8 +618,6 @@
int dlm_master_request_handler(net_msg *msg, u32 len, void *data);
int dlm_master_request_resp_handler(net_msg *msg, u32 len, void *data);
int dlm_assert_master_handler(net_msg *msg, u32 len, void *data);
-dlm_lock_resource * __dlm_lookup_lock(dlm_ctxt *dlm, struct qstr *lockname);
-void dlm_init_lockres(dlm_lock_resource *res, struct qstr *lockname);
void dlm_dump_everything(void);
void dlm_dump_dlm(dlm_ctxt *dlm);
@@ -635,7 +653,7 @@
/* EX incompatible with all non-NO_LOCK */
if (request == LKM_EXMODE)
return 0;
-
+
/* request must be PR, which is compatible with PR */
if (existing == LKM_PRMODE)
return 1;
@@ -656,7 +674,10 @@
return 0;
}
-static inline int dlm_mle_equal(dlm_ctxt *dlm, dlm_master_list_entry *mle, struct qstr *lockname)
+static inline int dlm_mle_equal(dlm_ctxt *dlm,
+ dlm_master_list_entry *mle,
+ const char *name,
+ unsigned int namelen)
{
dlm_lock_resource *res;
@@ -664,14 +685,13 @@
return 0;
if (mle->type == DLM_MLE_BLOCK) {
- if (lockname->len != mle->u.name.len ||
- strncmp(lockname->name, mle->u.name.name, lockname->len)!=0)
+ if (namelen != mle->u.name.len ||
+ strncmp(name, mle->u.name.name, namelen)!=0)
return 0;
} else {
res = mle->u.res;
- if (res->lockname.hash != lockname->hash ||
- res->lockname.len != lockname->len ||
- strncmp(res->lockname.name, lockname->name, lockname->len)!=0)
+ if (namelen != res->lockname.len ||
+ strncmp(res->lockname.name, name, namelen) != 0)
return 0;
}
return 1;
Modified: trunk/fs/ocfs2/dlm/dlmunlock.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmunlock.c 2005-02-22 00:45:45 UTC (rev 1899)
+++ trunk/fs/ocfs2/dlm/dlmunlock.c 2005-02-22 21:22:26 UTC (rev 1900)
@@ -158,7 +158,6 @@
spin_unlock(&lock->spinlock);
spin_unlock(&res->spinlock);
wake_up(&res->wq);
-
if (actions & DLM_UNLOCK_FREE_LOCK) {
#warning this must change to proper refcounting
@@ -177,10 +176,6 @@
return status;
}
-
-
-
-
/*
* locking:
* caller needs: none
@@ -202,7 +197,6 @@
struct iovec iov[2];
size_t iovlen = 1;
-
dlmprintk0("\n");
memset(&unlock, 0, sizeof(unlock));
@@ -260,20 +254,17 @@
{
dlm_ctxt *dlm = data;
dlm_unlock_lock *unlock = (dlm_unlock_lock *)msg->buf;
- dlm_lock_resource *res;
+ dlm_lock_resource *res = NULL;
struct list_head *iter;
dlm_lock *lock = NULL;
dlm_status status = DLM_NORMAL;
int found = 0, i;
dlm_lockstatus *lksb = NULL;
int ignore;
- struct qstr lockname;
u32 flags;
struct list_head *queue;
dlm_unlock_lock_to_host(unlock);
- lockname.name = unlock->name;
- lockname.len = unlock->namelen;
flags = unlock->flags;
if (flags & LKM_GET_LVB) {
@@ -287,12 +278,18 @@
return DLM_BADARGS;
}
+ if (unlock->namelen > DLM_LOCKID_NAME_MAX) {
+ printk("Invalid name length in unlock handler!\n");
+ return DLM_IVBUFLEN;
+ }
+
+ if (!dlm_grab(dlm))
+ return DLM_REJECTED;
+
dlmprintk("lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" : "none");
- lockname.hash = full_name_hash(lockname.name, lockname.len);
-
status = DLM_IVLOCKID;
- res = dlm_lookup_lock(dlm, &lockname);
+ res = dlm_lookup_lock(dlm, unlock->name, unlock->namelen);
if (!res)
goto not_found;
@@ -316,7 +313,7 @@
spin_unlock(&res->spinlock);
if (!found)
goto not_found;
-
+
/* lock was found on queue */
lksb = lock->lksb;
/* unlockast only called on originating node */
@@ -343,6 +340,11 @@
status = lksb->status;
}
+ if (res)
+ dlm_lockres_put(dlm, res);
+
+ dlm_put(dlm);
+
return status;
}
More information about the Ocfs2-commits
mailing list