free.
/* lock types */
char *ldlm_lockname[] = {
+ [0] "--",
[LCK_EX] "EX",
[LCK_PW] "PW",
[LCK_PR] "PR",
[LCK_CR] "CR",
[LCK_NL] "NL"
};
-
char *ldlm_typename[] = {
[LDLM_PLAIN] "PLN",
[LDLM_EXTENT] "EXT",
[LDLM_MDSINTENT] ldlm_intent_policy
};
-void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh)
-{
- lockh->addr = (__u64)(unsigned long)lock;
- lockh->cookie = lock->l_random;
-}
-
-/*
- * HANDLES
- */
-
-struct ldlm_lock *ldlm_handle2lock(struct lustre_handle *handle)
-{
- struct ldlm_lock *lock = NULL;
- ENTRY;
-
- if (!handle || !handle->addr)
- RETURN(NULL);
-
- lock = (struct ldlm_lock *)(unsigned long)(handle->addr);
- if (!kmem_cache_validate(ldlm_lock_slab, (void *)lock))
- RETURN(NULL);
-
- l_lock(&lock->l_resource->lr_namespace->ns_lock);
- if (lock->l_random != handle->cookie)
- GOTO(out, handle = NULL);
-
- if (lock->l_flags & LDLM_FL_DESTROYED)
- GOTO(out, handle = NULL);
-
- lock->l_refc++;
- EXIT;
- out:
- l_unlock(&lock->l_resource->lr_namespace->ns_lock);
- return lock;
-}
/*
* REFCOUNTED LOCK OBJECTS
if (lock->l_flags & LDLM_FL_DESTROYED) {
EXIT;
- ldlm_lock_put(lock);
return;
}
lock->l_flags = LDLM_FL_DESTROYED;
l_unlock(&lock->l_resource->lr_namespace->ns_lock);
ldlm_lock_put(lock);
- ldlm_lock_put(lock);
EXIT;
return;
}
RETURN(0);
}
+/*
+ * HANDLES
+ */
+
+void ldlm_lock2handle(struct ldlm_lock *lock, struct lustre_handle *lockh)
+{
+ lockh->addr = (__u64)(unsigned long)lock;
+ lockh->cookie = lock->l_random;
+}
+
+
+struct ldlm_lock *ldlm_handle2lock(struct lustre_handle *handle)
+{
+ struct ldlm_lock *lock = NULL;
+ ENTRY;
+
+ if (!handle || !handle->addr)
+ RETURN(NULL);
+
+ lock = (struct ldlm_lock *)(unsigned long)(handle->addr);
+ if (!kmem_cache_validate(ldlm_lock_slab, (void *)lock))
+ RETURN(NULL);
+
+ l_lock(&lock->l_resource->lr_namespace->ns_lock);
+ if (lock->l_random != handle->cookie)
+ GOTO(out, handle = NULL);
+
+ if (lock->l_flags & LDLM_FL_DESTROYED)
+ GOTO(out, handle = NULL);
+
+ ldlm_lock_get(lock);
+ EXIT;
+ out:
+ l_unlock(&lock->l_resource->lr_namespace->ns_lock);
+ return lock;
+}
+
+
+
static int ldlm_intent_policy(struct ldlm_lock *lock, void *req_cookie,
ldlm_mode_t mode, void *data)
{
*flags |= LDLM_FL_LOCK_CHANGED;
} else if (rc == ELDLM_LOCK_ABORTED) {
ldlm_lock_destroy(lock);
+ ldlm_lock_put(lock);
RETURN(rc);
}
}
EXPORT_SYMBOL(ldlm_lockname);
EXPORT_SYMBOL(ldlm_typename);
+EXPORT_SYMBOL(ldlm_handle2lock);
EXPORT_SYMBOL(ldlm_lock_match);
EXPORT_SYMBOL(ldlm_lock_addref);
EXPORT_SYMBOL(ldlm_lock_decref);
struct ptlrpc_request *req;
struct ldlm_lock *lock;
struct ldlm_request *body;
- struct ldlm_resource *res;
int rc, size = sizeof(*body);
ENTRY;
GOTO(out, rc);
ldlm_lock_cancel(lock);
- ldlm_reprocess_all(res);
+ ldlm_reprocess_all(lock->l_resource);
ldlm_lock_put(lock);
EXIT;
out:
return NULL;
}
-static int cleanup_resource(struct ldlm_resource *res, struct list_head *q)
+extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock);
+
+static void cleanup_resource(struct ldlm_resource *res, struct list_head *q)
{
struct list_head *tmp, *pos;
int rc = 0, client = res->lr_namespace->ns_client;
list_for_each_safe(tmp, pos, q) {
struct ldlm_lock *lock;
lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+ ldlm_lock_get(lock);
if (client) {
struct lustre_handle lockh;
CERROR("ldlm_cli_cancel: %d\n", rc);
LBUG();
}
- if (rc == ELDLM_RESOURCE_FREED)
- rc = 1;
} else {
CERROR("Freeing a lock still held by a client node.\n");
ldlm_resource_unlink_lock(lock);
ldlm_lock_destroy(lock);
-
- rc = ldlm_resource_put(res);
}
+ ldlm_lock_put(lock);
}
- RETURN(rc);
+ return;
}
int ldlm_namespace_free(struct ldlm_namespace *ns)
{
struct list_head *tmp, *pos;
- int i, rc;
+ int i;
if (!ns)
RETURN(ELDLM_OK);
list_for_each_safe(tmp, pos, &(ns->ns_hash[i])) {
struct ldlm_resource *res;
res = list_entry(tmp, struct ldlm_resource, lr_hash);
+ ldlm_resource_getref(res);
- rc = cleanup_resource(res, &res->lr_granted);
- if (!rc)
- rc = cleanup_resource(res, &res->lr_converting);
- if (!rc)
- rc = cleanup_resource(res, &res->lr_waiting);
-
- if (rc == 0) {
+ cleanup_resource(res, &res->lr_granted);
+ cleanup_resource(res, &res->lr_converting);
+ cleanup_resource(res, &res->lr_waiting);
+
+ if (!ldlm_resource_put(res)) {
CERROR("Resource refcount nonzero (%d) after "
"lock cleanup; forcing cleanup.\n",
atomic_read(&res->lr_refcount));
ldlm_resource_dump(res);
atomic_set(&res->lr_refcount, 1);
- rc = ldlm_resource_put(res);
+ ldlm_resource_put(res);
}
}
}
GOTO(out_create_de, rc = -EIO);
}
} else {
- lock = lustre_handle2object(&lockh);
+ lock = ldlm_handle2lock(&lockh);
LDLM_DEBUG(lock, "matched");
}
ldlm_lock_dump((void *)(unsigned long)lockh.addr);