From 0e250106c61fb246d2d349defdd49fa66d74a985 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 2 Oct 2013 18:14:16 -0700 Subject: [PATCH] LU-3027 lov: to not modify lov lock when sublock is canceled Otherwise it will cause wrong lock to be enqueued. lls_ever_canceled is introduced to solve potential performance problem by this patch. Signed-off-by: Jinshan Xiong Change-Id: I1ea62902c9d1a468f5952f30a8dc5dec22b8bb1c Reviewed-on: http://review.whamcloud.com/7841 Reviewed-by: Bobi Jam Reviewed-by: Lai Siyao Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/lov/lov_cl_internal.h | 3 ++- lustre/lov/lov_lock.c | 3 +++ lustre/lov/lovsub_lock.c | 10 ++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index 13c2f5a..8a90fec 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -303,7 +303,8 @@ struct lov_lock { * Set when sub-lock was canceled, while top-lock was being * used, or unused. */ - unsigned int lls_cancel_race:1; + unsigned int lls_cancel_race:1, + lls_ever_canceled:1; /** * An array of sub-locks * diff --git a/lustre/lov/lov_lock.c b/lustre/lov/lov_lock.c index 417d025..f515e66 100644 --- a/lustre/lov/lov_lock.c +++ b/lustre/lov/lov_lock.c @@ -1023,6 +1023,9 @@ static int lov_lock_fits_into(const struct lu_env *env, if (need->cld_enq_flags != lov->lls_orig.cld_enq_flags) return 0; + if (lov->lls_ever_canceled) + return 0; + if (need->cld_mode == CLM_GROUP) /* * always allow to match group lock. diff --git a/lustre/lov/lovsub_lock.c b/lustre/lov/lovsub_lock.c index 120ca949..1e7988f 100644 --- a/lustre/lov/lovsub_lock.c +++ b/lustre/lov/lovsub_lock.c @@ -221,7 +221,11 @@ int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov, pd->cld_gid = parent_descr->cld_gid; lovsub_lock_descr_map(d, subobj->lso_super, subobj->lso_index, pd); - /* LU-3027: only update extent of lock */ + /* LU-3027: only update extent of lock, plus the change in + * lovsub_lock_delete() that lock extent is modified after a sublock + * is canceled, we can make sure that the lock extent won't be updated + * any more. Therefore, lov_lock_fits_into() will always find feasible + * locks */ lov->lls_sub[idx].sub_got.cld_start = d->cld_start; lov->lls_sub[idx].sub_got.cld_end = d->cld_end; /* @@ -300,6 +304,7 @@ static int lovsub_lock_delete_one(const struct lu_env *env, RETURN(0); result = 0; + lov->lls_ever_canceled = 1; switch (parent->cll_state) { case CLS_ENQUEUED: /* See LU-1355 for the case that a glimpse lock is @@ -418,15 +423,12 @@ static void lovsub_lock_delete(const struct lu_env *env, struct lov_lock *lov; struct lov_lock_link *scan; struct lov_lock_link *temp; - struct lov_lock_sub *subdata; restart = 0; cfs_list_for_each_entry_safe(scan, temp, &sub->lss_parents, lll_list) { lov = scan->lll_super; - subdata = &lov->lls_sub[scan->lll_idx]; lovsub_parent_lock(env, lov); - subdata->sub_got = subdata->sub_descr; lov_lock_unlink(env, scan, sub); restart = lovsub_lock_delete_one(env, child, lov); lovsub_parent_unlock(env, lov); -- 1.8.3.1