X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fldlm%2Fl_lock.c;h=b652097355ca025fe4a40ee4f2902b99e253b4d4;hb=55e8287b7024ee4ac280806caea9636dd454a0ed;hp=db072e05b0479d593382c0391b7b4d6f8cefde54;hpb=544bbd4c7f485b5cc9a0109f6de288772bb5019a;p=fs%2Flustre-release.git diff --git a/lustre/ldlm/l_lock.c b/lustre/ldlm/l_lock.c index db072e0..b652097 100644 --- a/lustre/ldlm/l_lock.c +++ b/lustre/ldlm/l_lock.c @@ -20,15 +20,14 @@ * */ - - +#define DEBUG_SUBSYSTEM S_LDLM +#ifdef __KERNEL__ #include #include #include #include #include #include -#include #include #include @@ -42,55 +41,46 @@ #include #include #include +#else +#include +#endif -#define DEBUG_SUBSYSTEM S_LDLM - -#include +#include #include -/* invariants: - - only the owner of the lock changes l_owner/l_depth - - if a non-owner changes or checks the variables a spin lock is taken -*/ - -void l_lock_init(struct lustre_lock *lock) +/* + * ldlm locking uses resource to serialize access to locks + * but there is a case when we change resource of lock upon + * enqueue reply. we rely on that lock->l_resource = new_res + * is atomic + */ +struct ldlm_resource * lock_res_and_lock(struct ldlm_lock *lock) { - sema_init(&lock->l_sem, 1); - spin_lock_init(&lock->l_spin); -} + struct ldlm_resource *res = lock->l_resource; -void l_lock(struct lustre_lock *lock) -{ - int owner = 0; - spin_lock(&lock->l_spin); - if (lock->l_owner == current) { - owner = 1; - } - spin_unlock(&lock->l_spin); - if (owner) - ++lock->l_depth; - else { - down(&lock->l_sem); - spin_lock(&lock->l_spin); - lock->l_owner = current; - lock->l_depth = 0; - spin_unlock(&lock->l_spin); - } + if (!res->lr_namespace->ns_client) { + /* on server-side resource of lock doesn't change */ + lock_res(res); + return res; + } + + lock_bitlock(lock); + res = lock->l_resource; + lock_res(res); + return res; } -void l_unlock(struct lustre_lock *lock) +void unlock_res_and_lock(struct ldlm_lock *lock) { - if (lock->l_owner != current) - LBUG(); - if (lock->l_depth < 0) - LBUG(); + struct ldlm_resource *res = lock->l_resource; - spin_lock(&lock->l_spin); - if (--lock->l_depth < 0) { - lock->l_owner = NULL; - spin_unlock(&lock->l_spin); - up(&lock->l_sem); - return ; + if (!res->lr_namespace->ns_client) { + /* on server-side resource of lock doesn't change */ + unlock_res(res); + return; } - spin_unlock(&lock->l_spin); + + unlock_res(res); + unlock_bitlock(lock); } +