#include "ldlm_internal.h"
+struct kmem_cache *ldlm_glimpse_work_kmem;
+EXPORT_SYMBOL(ldlm_glimpse_work_kmem);
+
/* lock types */
char *ldlm_lockname[] = {
[0] = "--",
* otherwise, the lock hasn't been in the LRU list.
* \retval 1 the lock was in LRU list and removed.
*/
-int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, cfs_time_t last_use)
+int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, ktime_t last_use)
{
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
int rc = 0;
}
spin_lock(&ns->ns_lock);
- if (last_use == 0 || last_use == lock->l_last_used)
+ if (!ktime_compare(last_use, ktime_set(0, 0)) ||
+ !ktime_compare(last_use, lock->l_last_used))
rc = ldlm_lock_remove_from_lru_nolock(lock);
spin_unlock(&ns->ns_lock);
{
struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
- lock->l_last_used = cfs_time_current();
+ lock->l_last_used = ktime_get();
LASSERT(list_empty(&lock->l_lru));
LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
list_add_tail(&lock->l_lru, &ns->ns_unused_list);
rc = 1;
LDLM_LOCK_RELEASE(lock);
-
- if ((gl_work->gl_flags & LDLM_GL_WORK_NOFREE) == 0)
+ if (gl_work->gl_flags & LDLM_GL_WORK_SLAB_ALLOCATED)
+ OBD_SLAB_FREE_PTR(gl_work, ldlm_glimpse_work_kmem);
+ else
OBD_FREE_PTR(gl_work);
RETURN(rc);
res = ldlm_resource_getref(lock->l_resource);
- ldlm_res_lvbo_update(res, NULL, 1);
+ ldlm_lvbo_update(res, lock, NULL, 1);
ldlm_lock_cancel(lock);
if (!exp->exp_obd->obd_stopping)
ldlm_reprocess_all(res);
"left on hash table %d.\n", exp, ecl.ecl_loop,
atomic_read(&exp->exp_lock_hash->hs_count));
+ if (ecl.ecl_loop > 0 &&
+ atomic_read(&exp->exp_lock_hash->hs_count) == 0 &&
+ exp->exp_obd->obd_stopping)
+ ldlm_reprocess_recovery_done(exp->exp_obd->obd_namespace);
+
return ecl.ecl_loop;
}
/**
* Downgrade an exclusive lock.
*
- * A fast variant of ldlm_lock_convert for convertion of exclusive
- * locks. The convertion is always successful.
+ * A fast variant of ldlm_lock_convert for convertion of exclusive locks. The
+ * convertion may fail if lock was canceled before downgrade, but it doesn't
+ * indicate any problem, because such lock has no reader or writer, and will
+ * be released soon.
* Used by Commit on Sharing (COS) code.
*
* \param lock A lock to convert
*/
void ldlm_lock_downgrade(struct ldlm_lock *lock, enum ldlm_mode new_mode)
{
- ENTRY;
+ ENTRY;
- LASSERT(lock->l_granted_mode & (LCK_PW | LCK_EX));
- LASSERT(new_mode == LCK_COS);
+ LASSERT(new_mode == LCK_COS);
- lock_res_and_lock(lock);
- ldlm_resource_unlink_lock(lock);
- /*
- * Remove the lock from pool as it will be added again in
- * ldlm_grant_lock() called below.
- */
- ldlm_pool_del(&ldlm_lock_to_ns(lock)->ns_pool, lock);
+ lock_res_and_lock(lock);
- lock->l_req_mode = new_mode;
- ldlm_grant_lock(lock, NULL);
- unlock_res_and_lock(lock);
- ldlm_reprocess_all(lock->l_resource);
+ if (!(lock->l_granted_mode & (LCK_PW | LCK_EX))) {
+ unlock_res_and_lock(lock);
- EXIT;
+ LASSERT(lock->l_granted_mode == LCK_MINMODE);
+ LDLM_DEBUG(lock, "lock was canceled before downgrade");
+ RETURN_EXIT;
+ }
+
+ ldlm_resource_unlink_lock(lock);
+ /*
+ * Remove the lock from pool as it will be added again in
+ * ldlm_grant_lock() called below.
+ */
+ ldlm_pool_del(&ldlm_lock_to_ns(lock)->ns_pool, lock);
+ lock->l_req_mode = new_mode;
+ ldlm_grant_lock(lock, NULL);
+
+ unlock_res_and_lock(lock);
+
+ ldlm_reprocess_all(lock->l_resource);
+
+ EXIT;
}
EXPORT_SYMBOL(ldlm_lock_downgrade);
{
va_list args;
struct obd_export *exp = lock->l_export;
- struct ldlm_resource *resource = lock->l_resource;
+ struct ldlm_resource *resource = NULL;
char *nid = "local";
+ /* on server-side resource of lock doesn't change */
+ if ((lock->l_flags & LDLM_FL_NS_SRV) != 0) {
+ if (lock->l_resource != NULL)
+ resource = ldlm_resource_getref(lock->l_resource);
+ } else if (spin_trylock(&lock->l_lock)) {
+ if (lock->l_resource != NULL)
+ resource = ldlm_resource_getref(lock->l_resource);
+ spin_unlock(&lock->l_lock);
+ }
+
va_start(args, fmt);
if (exp && exp->exp_connection) {
case LDLM_IBITS:
libcfs_debug_vmsg2(msgdata, fmt, args,
" ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
- "res: "DLDLMRES" bits %#llx rrc: %d type: %s "
+ "res: "DLDLMRES" bits %#llx/%#llx rrc: %d type: %s "
"flags: %#llx nid: %s remote: %#llx expref: %d "
"pid: %u timeout: %lu lvb_type: %d\n",
ldlm_lock_to_ns_name(lock),
ldlm_lockname[lock->l_req_mode],
PLDLMRES(resource),
lock->l_policy_data.l_inodebits.bits,
+ lock->l_policy_data.l_inodebits.try_bits,
atomic_read(&resource->lr_refcount),
ldlm_typename[resource->lr_type],
lock->l_flags, nid, lock->l_remote_handle.cookie,
break;
}
va_end(args);
+ ldlm_resource_putref(resource);
}
EXPORT_SYMBOL(_ldlm_lock_debug);