From 0b0671e8f939d17612829d3a2f8ad013be416945 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 14 Jul 2019 21:11:56 -0400 Subject: [PATCH] LU-4423 obdclass: use list_sort() to sort a list. Rather than a bespoke bubble-sort, use list_sort() to sort this linked list. As this would become a 1-line function that is only called once, call list_sort() directly from the one call site. Linux-commit: e714d3559e964d1547d20b54ad5fd6bbb3401f56 Signed-off-by: NeilBrown Change-Id: Ied197a4fdba43d793c5ebbb9afc837a986609469 Reviewed-on: https://review.whamcloud.com/35512 Tested-by: jenkins Reviewed-by: Patrick Farrell Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/obdclass/cl_io.c | 64 ++++++++++++------------------------------------- 1 file changed, 15 insertions(+), 49 deletions(-) diff --git a/lustre/obdclass/cl_io.c b/lustre/obdclass/cl_io.c index 620cfa1..ce59926 100644 --- a/lustre/obdclass/cl_io.c +++ b/lustre/obdclass/cl_io.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -219,59 +220,20 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io, } EXPORT_SYMBOL(cl_io_rw_init); -static int cl_lock_descr_sort(const struct cl_lock_descr *d0, - const struct cl_lock_descr *d1) +static int cl_lock_descr_cmp(void *priv, + struct list_head *a, struct list_head *b) { + const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, + cill_linkage); + const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, + cill_linkage); + const struct cl_lock_descr *d0 = &l0->cill_descr; + const struct cl_lock_descr *d1 = &l1->cill_descr; + return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu), lu_object_fid(&d1->cld_obj->co_lu)); } -/* - * Sort locks in lexicographical order of their (fid, start-offset) pairs. - */ -static void cl_io_locks_sort(struct cl_io *io) -{ - int done = 0; - - ENTRY; - /* hidden treasure: bubble sort for now. */ - do { - struct cl_io_lock_link *curr; - struct cl_io_lock_link *prev; - struct cl_io_lock_link *temp; - - done = 1; - prev = NULL; - - list_for_each_entry_safe(curr, temp, &io->ci_lockset.cls_todo, - cill_linkage) { - if (prev != NULL) { - switch (cl_lock_descr_sort(&prev->cill_descr, - &curr->cill_descr)) { - case 0: - /* - * IMPOSSIBLE: Identical locks are - * already removed at - * this point. - */ - default: - LBUG(); - case +1: - list_move_tail(&curr->cill_linkage, - &prev->cill_linkage); - done = 0; - continue; /* don't change prev: it's - * still "previous" */ - case -1: /* already in order */ - break; - } - } - prev = curr; - } - } while (!done); - EXIT; -} - static void cl_lock_descr_merge(struct cl_lock_descr *d0, const struct cl_lock_descr *d1) { @@ -354,7 +316,11 @@ int cl_io_lock(const struct lu_env *env, struct cl_io *io) break; } if (result == 0) { - cl_io_locks_sort(io); + /* + * Sort locks in lexicographical order of their (fid, + * start-offset) pairs to avoid deadlocks. + */ + list_sort(NULL, &io->ci_lockset.cls_todo, cl_lock_descr_cmp); result = cl_lockset_lock(env, io, &io->ci_lockset); } if (result != 0) -- 1.8.3.1