From 810f2a5fef577b4f0f6a58ab234cf29afd96c748 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Fri, 7 Jun 2019 22:34:03 -0700 Subject: [PATCH] LU-12328 flr: preserve last read mirror This patch preserves the mirror that has been read successfully so that all subsequent I/O can take this advantage it and avoid trying to read unavailable OSTs. Signed-off-by: Jinshan Xiong Change-Id: I806f936340db7c73228048edf21d5ecbed4b3c6c Reviewed-on: https://review.whamcloud.com/35111 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/lov/lov_cl_internal.h | 9 ++++++++- lustre/lov/lov_io.c | 20 ++++++++++++++++++-- lustre/lov/lov_object.c | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index a72d455..7249f88 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -312,8 +312,15 @@ struct lov_object { */ int lo_preferred_mirror; /** + * The last mirror that has been read successfully. + * This field is maintained so that subsequent read + * can take the advantage of last retries and avoid + * reading some unavailable OSTs. + */ + int lo_last_read_mirror; + /** * For FLR: the lock to protect access to - * lo_preferred_mirror. + * lo_last_read_mirror. */ spinlock_t lo_write_lock; /** diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index 2fa95f5..415a91b 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -390,15 +390,31 @@ static int lov_io_mirror_init(struct lov_io *lio, struct lov_object *obj, /* reset the mirror index if layout has changed */ lio->lis_mirror_layout_gen != obj->lo_lsm->lsm_layout_gen) { lio->lis_mirror_layout_gen = obj->lo_lsm->lsm_layout_gen; - index = lio->lis_mirror_index = comp->lo_preferred_mirror; + index = lio->lis_mirror_index = comp->lo_last_read_mirror; } else { index = lio->lis_mirror_index; LASSERT(index >= 0); /* move mirror index to the next one */ - index = (index + 1) % comp->lo_mirror_count; + spin_lock(&comp->lo_write_lock); + if (index == comp->lo_last_read_mirror) { + do { + index = (index + 1) % comp->lo_mirror_count; + if (comp->lo_mirrors[index].lre_valid) + break; + } while (index != comp->lo_last_read_mirror); + + /* reset last read replica so that other threads can + * take advantage of our retries. */ + comp->lo_last_read_mirror = index; + } else { + /* last read index was moved by other thread */ + index = comp->lo_last_read_mirror; + } + spin_unlock(&comp->lo_write_lock); } + /* make sure the mirror chosen covers the extent we'll read */ for (i = 0; i < comp->lo_mirror_count; i++) { struct lu_extent ext = { .e_start = lio->lis_pos, .e_end = lio->lis_pos + 1 }; diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index ae535c0..632a4d3 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -783,6 +783,7 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev, } LASSERT(comp->lo_preferred_mirror >= 0); + comp->lo_last_read_mirror = comp->lo_preferred_mirror; EXIT; out: -- 1.8.3.1