Whamcloud - gitweb
LU-12328 flr: preserve last read mirror 11/35111/2
authorJinshan Xiong <jinshan.xiong@uber.com>
Sat, 8 Jun 2019 05:34:03 +0000 (22:34 -0700)
committerOleg Drokin <green@whamcloud.com>
Sun, 7 Jul 2019 15:15:58 +0000 (15:15 +0000)
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 <jinshan.xiong@gmail.com>
Change-Id: I806f936340db7c73228048edf21d5ecbed4b3c6c
Reviewed-on: https://review.whamcloud.com/35111
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/lov/lov_cl_internal.h
lustre/lov/lov_io.c
lustre/lov/lov_object.c

index a72d455..7249f88 100644 (file)
@@ -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;
                        /**
index 2fa95f5..415a91b 100644 (file)
@@ -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 };
index ae535c0..632a4d3 100644 (file)
@@ -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: