LDLM_LOCK_RELEASE(lock);
continue;
}
- lock->l_resource->lr_namespace->ns_timeouts++;
+ ldlm_lock_to_ns(lock)->ns_timeouts++;
LDLM_ERROR(lock, "lock callback timer expired after %lds: "
"evicting client at %s ",
cfs_time_current_sec()- lock->l_last_activity,
ldlm_failed_ast(lock, rc, ast_type);
}
} else if (rc) {
- if (rc == -EINVAL)
+ if (rc == -EINVAL) {
+ struct ldlm_resource *res = lock->l_resource;
LDLM_DEBUG(lock, "client (nid %s) returned %d"
" from %s AST - normal race",
libcfs_nid2str(peer.nid),
req->rq_repmsg ?
lustre_msg_get_status(req->rq_repmsg) : -1,
ast_type);
- else
+ if (res) {
+ /* update lvbo to return proper attributes.
+ * see bug 23174 */
+ ldlm_resource_getref(res);
+ ldlm_res_lvbo_update(res, NULL, 1);
+ ldlm_resource_putref(res);
+ }
+
+ } else {
LDLM_ERROR(lock, "client (nid %s) returned %d "
"from %s AST", libcfs_nid2str(peer.nid),
(req->rq_repmsg != NULL) ?
lustre_msg_get_status(req->rq_repmsg) : 0,
ast_type);
+ }
ldlm_lock_cancel(lock);
/* Server-side AST functions are called from ldlm_reprocess_all,
* which needs to be told to please restart its reprocessing. */
lock = req->rq_async_args.pointer_arg[1];
LASSERT(lock != NULL);
if (rc != 0) {
- /* If client canceled the lock but the cancel has not
- * been received yet, we need to update lvbo to have the
- * proper attributes cached. */
- if (rc == -EINVAL && arg->type == LDLM_BL_CALLBACK)
- ldlm_res_lvbo_update(lock->l_resource, NULL, 1);
rc = ldlm_handle_ast_error(lock, req, rc,
arg->type == LDLM_BL_CALLBACK
? "blocking" : "completion");
if (req == NULL)
RETURN(-ENOMEM);
- lock_res_and_lock(lock);
- if (lock->l_resource->lr_lvb_len)
+ /* server namespace, doesn't need lock */
+ if (lock->l_resource->lr_lvb_len) {
req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_CLIENT,
lock->l_resource->lr_lvb_len);
- unlock_res_and_lock(lock);
+ }
rc = ptlrpc_request_pack(req, LUSTRE_DLM_VERSION, LDLM_CP_CALLBACK);
if (rc) {
if (lock->l_resource->lr_lvb_len) {
void *lvb = req_capsule_client_get(&req->rq_pill, &RMF_DLM_LVB);
- lock_res_and_lock(lock);
+ cfs_down(&lock->l_resource->lr_lvb_sem);
memcpy(lvb, lock->l_resource->lr_lvb_data,
lock->l_resource->lr_lvb_len);
- unlock_res_and_lock(lock);
+ cfs_up(&lock->l_resource->lr_lvb_sem);
}
LDLM_DEBUG(lock, "server preparing completion AST (after %lds wait)",
/* Server-side enqueue wait time estimate, used in
__ldlm_add_waiting_lock to set future enqueue timers */
if (total_enqueue_wait < ldlm_get_enq_timeout(lock))
- at_measured(&lock->l_resource->lr_namespace->ns_at_estimate,
+ at_measured(ldlm_lock_to_ns_at(lock),
total_enqueue_wait);
else
/* bz18618. Don't add lock enqueue time we spend waiting for a
LDLM_DEBUG(lock, "lock completed after %lus; estimate was %ds. "
"It is likely that a previous callback timed out.",
total_enqueue_wait,
- at_get(&lock->l_resource->lr_namespace->ns_at_estimate));
+ at_get(ldlm_lock_to_ns_at(lock)));
ptlrpc_request_set_replen(req);
body->lock_handle[0] = lock->l_remote_handle;
ldlm_lock2desc(lock, &body->lock_desc);
- lock_res_and_lock(lock);
+ /* server namespace, doesn't need lock */
req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
lock->l_resource->lr_lvb_len);
- unlock_res_and_lock(lock);
res = lock->l_resource;
ptlrpc_request_set_replen(req);
LDLM_DEBUG(lock, "server-side enqueue handler, new lock created");
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_ENQUEUE_BLOCKED, obd_timeout * 2);
- /* Don't enqueue a lock onto the export if it has already
- * been evicted. Cancel it now instead. (bug 3822) */
- if (req->rq_export->exp_failed) {
- LDLM_ERROR(lock, "lock on destroyed export %p", req->rq_export);
+ /* Don't enqueue a lock onto the export if it is been disonnected
+ * due to eviction (bug 3822) or server umount (bug 24324).
+ * Cancel it now instead. */
+ if (req->rq_export->exp_disconnected) {
+ LDLM_ERROR(lock, "lock on disconnected export %p",
+ req->rq_export);
GOTO(out, rc = -ENOTCONN);
}
* local_lock_enqueue by the policy function. */
cookie = req;
} else {
- lock_res_and_lock(lock);
if (lock->l_resource->lr_lvb_len) {
req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB,
RCL_SERVER,
lock->l_resource->lr_lvb_len);
}
- unlock_res_and_lock(lock);
if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR))
GOTO(out, rc = -ENOMEM);
dlm_rep->lock_flags |= dlm_req->lock_flags & LDLM_INHERIT_FLAGS;
lock->l_flags |= dlm_req->lock_flags & LDLM_INHERIT_FLAGS;
- /* Don't move a pending lock onto the export if it has already
- * been evicted. Cancel it now instead. (bug 5683) */
- if (unlikely(req->rq_export->exp_failed ||
+ /* Don't move a pending lock onto the export if it has already been
+ * disconnected due to eviction (bug 5683) or server umount (bug 24324).
+ * Cancel it now instead. */
+ if (unlikely(req->rq_export->exp_disconnected ||
OBD_FAIL_CHECK(OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT))) {
LDLM_ERROR(lock, "lock on destroyed export %p", req->rq_export);
rc = -ENOTCONN;
LDLM_DEBUG(lock, "server-side enqueue handler, sending reply"
"(err=%d, rc=%d)", err, rc);
- lock_res_and_lock(lock);
if (rc == 0) {
if (lock->l_resource->lr_lvb_len > 0) {
void *lvb;
LASSERTF(lvb != NULL, "req %p, lock %p\n",
req, lock);
+ cfs_down(&lock->l_resource->lr_lvb_sem);
memcpy(lvb, lock->l_resource->lr_lvb_data,
lock->l_resource->lr_lvb_len);
+ cfs_up(&lock->l_resource->lr_lvb_sem);
}
} else {
+ lock_res_and_lock(lock);
ldlm_resource_unlink_lock(lock);
ldlm_lock_destroy_nolock(lock);
+ unlock_res_and_lock(lock);
}
- unlock_res_and_lock(lock);
if (!err && dlm_req->lock_desc.l_resource.lr_type != LDLM_FLOCK)
ldlm_reprocess_all(lock->l_resource);
RETURN(0);
}
-void ldlm_revoke_lock_cb(void *obj, void *data)
+int ldlm_revoke_lock_cb(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+ cfs_hlist_node_t *hnode, void *data)
+
{
cfs_list_t *rpc_list = data;
- struct ldlm_lock *lock = obj;
+ struct ldlm_lock *lock = cfs_hash_object(hs, hnode);
lock_res_and_lock(lock);
if (lock->l_req_mode != lock->l_granted_mode) {
unlock_res_and_lock(lock);
- return;
+ return 0;
}
LASSERT(lock->l_resource);
if (lock->l_resource->lr_type != LDLM_IBITS &&
lock->l_resource->lr_type != LDLM_PLAIN) {
unlock_res_and_lock(lock);
- return;
+ return 0;
}
if (lock->l_flags & LDLM_FL_AST_SENT) {
unlock_res_and_lock(lock);
- return;
+ return 0;
}
LASSERT(lock->l_blocking_ast);
LDLM_LOCK_GET(lock);
unlock_res_and_lock(lock);
+ return 0;
}
void ldlm_revoke_export_locks(struct obd_export *exp)
/* Not fatal if racy and have a few too many threads */
if (unlikely(busy < blp->blp_max_threads &&
- busy >= cfs_atomic_read(&blp->blp_num_threads)))
+ busy >= cfs_atomic_read(&blp->blp_num_threads) &&
+ !blwi->blwi_mem_pressure))
/* discard the return value, we tried */
ldlm_bl_thread_start(blp);
} else {
ldlm_export_lock_key(cfs_hlist_node_t *hnode)
{
struct ldlm_lock *lock;
- ENTRY;
lock = cfs_hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
- RETURN(&lock->l_remote_handle);
+ return &lock->l_remote_handle;
+}
+
+static void
+ldlm_export_lock_keycpy(cfs_hlist_node_t *hnode, void *key)
+{
+ struct ldlm_lock *lock;
+
+ lock = cfs_hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+ lock->l_remote_handle = *(struct lustre_handle *)key;
}
static int
-ldlm_export_lock_compare(void *key, cfs_hlist_node_t *hnode)
+ldlm_export_lock_keycmp(void *key, cfs_hlist_node_t *hnode)
{
- ENTRY;
- RETURN(lustre_handle_equal(ldlm_export_lock_key(hnode), key));
+ return lustre_handle_equal(ldlm_export_lock_key(hnode), key);
}
static void *
-ldlm_export_lock_get(cfs_hlist_node_t *hnode)
+ldlm_export_lock_object(cfs_hlist_node_t *hnode)
+{
+ return cfs_hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+}
+
+static void
+ldlm_export_lock_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
{
struct ldlm_lock *lock;
- ENTRY;
lock = cfs_hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
LDLM_LOCK_GET(lock);
-
- RETURN(lock);
}
-static void *
-ldlm_export_lock_put(cfs_hlist_node_t *hnode)
+static void
+ldlm_export_lock_put(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
{
struct ldlm_lock *lock;
- ENTRY;
lock = cfs_hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
LDLM_LOCK_RELEASE(lock);
-
- RETURN(lock);
}
static cfs_hash_ops_t ldlm_export_lock_ops = {
- .hs_hash = ldlm_export_lock_hash,
- .hs_key = ldlm_export_lock_key,
- .hs_compare = ldlm_export_lock_compare,
- .hs_get = ldlm_export_lock_get,
- .hs_put = ldlm_export_lock_put
+ .hs_hash = ldlm_export_lock_hash,
+ .hs_key = ldlm_export_lock_key,
+ .hs_keycmp = ldlm_export_lock_keycmp,
+ .hs_keycpy = ldlm_export_lock_keycpy,
+ .hs_object = ldlm_export_lock_object,
+ .hs_get = ldlm_export_lock_get,
+ .hs_put = ldlm_export_lock_put,
+ .hs_put_locked = ldlm_export_lock_put,
};
int ldlm_init_export(struct obd_export *exp)
exp->exp_lock_hash =
cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid),
- HASH_EXP_LOCK_CUR_BITS, HASH_EXP_LOCK_MAX_BITS,
- &ldlm_export_lock_ops, CFS_HASH_REHASH);
+ HASH_EXP_LOCK_CUR_BITS,
+ HASH_EXP_LOCK_MAX_BITS,
+ HASH_EXP_LOCK_BKT_BITS, 0,
+ CFS_HASH_MIN_THETA, CFS_HASH_MAX_THETA,
+ &ldlm_export_lock_ops,
+ CFS_HASH_DEFAULT | CFS_HASH_REHASH_KEY |
+ CFS_HASH_NBLK_CHANGE);
if (!exp->exp_lock_hash)
RETURN(-ENOMEM);
GOTO(out_thread, rc);
}
- rc = ptlrpc_start_threads(NULL, ldlm_state->ldlm_cancel_service);
+ rc = ptlrpc_start_threads(ldlm_state->ldlm_cancel_service);
if (rc)
GOTO(out_thread, rc);
- rc = ptlrpc_start_threads(NULL, ldlm_state->ldlm_cb_service);
+ rc = ptlrpc_start_threads(ldlm_state->ldlm_cb_service);
if (rc)
GOTO(out_thread, rc);
EXPORT_SYMBOL(ldlm_replay_locks);
EXPORT_SYMBOL(ldlm_resource_foreach);
EXPORT_SYMBOL(ldlm_namespace_foreach);
-EXPORT_SYMBOL(ldlm_namespace_foreach_res);
EXPORT_SYMBOL(ldlm_resource_iterate);
EXPORT_SYMBOL(ldlm_cancel_resource_local);
EXPORT_SYMBOL(ldlm_cli_cancel_list_local);