diff options
author | Jinshan Xiong <jinshan.xiong@intel.com> | 2017-02-18 16:47:06 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-06 09:16:59 +0100 |
commit | 46ff82f9561be47a37385d5a35fb1eb6c8644930 (patch) | |
tree | 183f6d2774fc2da747cc5050b8976071a9602d3f /drivers/staging/lustre/lustre/ldlm/ldlm_request.c | |
parent | 5fd8f8b8d5e4aff6c05229bcd51c1852d4fa04f5 (diff) | |
download | op-kernel-dev-46ff82f9561be47a37385d5a35fb1eb6c8644930.zip op-kernel-dev-46ff82f9561be47a37385d5a35fb1eb6c8644930.tar.gz |
staging: lustre: ldlm: handle ldlm lock cancel race when evicting client.
A ldlm lock could be canceled simutaneously by ldlm bl thread and
cleanup_resource(). In this case, only one side will win the race
and the other side should wait for the work to complete. Eviction
on group lock is now well supported.
Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6271
Reviewed-on: http://review.whamcloud.com/16456
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Signed-off-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/lustre/lustre/ldlm/ldlm_request.c')
-rw-r--r-- | drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index ebfda36..84eeaa5 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1029,13 +1029,23 @@ int ldlm_cli_cancel(const struct lustre_handle *lockh, struct ldlm_lock *lock; LIST_HEAD(cancels); - /* concurrent cancels on the same handle can happen */ - lock = ldlm_handle2lock_long(lockh, LDLM_FL_CANCELING); + lock = ldlm_handle2lock_long(lockh, 0); if (!lock) { LDLM_DEBUG_NOLOCK("lock is already being destroyed"); return 0; } + lock_res_and_lock(lock); + /* Lock is being canceled and the caller doesn't want to wait */ + if (ldlm_is_canceling(lock) && (cancel_flags & LCF_ASYNC)) { + unlock_res_and_lock(lock); + LDLM_LOCK_RELEASE(lock); + return 0; + } + + ldlm_set_canceling(lock); + unlock_res_and_lock(lock); + rc = ldlm_cli_cancel_local(lock); if (rc == LDLM_FL_LOCAL_ONLY || cancel_flags & LCF_LOCAL) { LDLM_LOCK_RELEASE(lock); |