Whamcloud - gitweb
LU-15829 llite: don't use a kms if it invalid. 95/47395/6
authorAlexey Lyashkov <alexey.lyashkov@hpe.com>
Thu, 19 May 2022 17:35:18 +0000 (20:35 +0300)
committerOleg Drokin <green@whamcloud.com>
Mon, 12 Sep 2022 02:52:57 +0000 (02:52 +0000)
Lockless DIO don't update a KMS as other IO type does,
it caused a situation when next read don't known a real file size
to be read. Lets avoid using an invalid KMS.

Fixes: 6bce5367 (LU-4198 clio: turn on lockless for some kind of IO)
Signed-off-by: Alexey Lyashkov <alexey.lyashkov@hpe.com>
Change-Id: Ie71d3f3cc24fc16c03ed07f9f5a3a17c7fdfa684
Reviewed-on: https://review.whamcloud.com/47395
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/cl_object.h
lustre/llite/vvp_io.c
lustre/lov/lov_internal.h
lustre/lov/lov_merge.c
lustre/lov/lov_object.c
lustre/tests/sanity.sh
lustre/tests/test-framework.sh

index 2ef9c84..bc534e0 100644 (file)
@@ -140,6 +140,8 @@ struct cl_device {
 struct cl_attr {
         /** Object size, in bytes */
         loff_t cat_size;
+
+       unsigned int cat_kms_valid:1;
         /**
          * Known minimal size, in bytes.
          *
index 9ae65ac..5701737 100644 (file)
@@ -150,7 +150,7 @@ static int vvp_prep_size(const struct lu_env *env, struct cl_object *obj,
        result = cl_object_attr_get(env, obj, attr);
        if (result == 0) {
                kms = attr->cat_kms;
-               if (pos > kms) {
+               if (pos > kms || !attr->cat_kms_valid) {
                        /*
                         * A glimpse is necessary to determine whether we
                         * return a short read (B) or some zeroes at the end
index 9341d2e..9e82077 100644 (file)
@@ -261,7 +261,7 @@ extern struct lu_kmem_descr lov_caches[];
 
 /* lov_merge.c */
 int lov_merge_lvb_kms(struct lov_stripe_md *lsm, int index,
-                      struct ost_lvb *lvb, __u64 *kms_place);
+                     struct cl_attr *attr);
 
 /* lov_offset.c */
 loff_t stripe_width(struct lov_stripe_md *lsm, unsigned int index);
index 30fb5b4..09d2299 100644 (file)
@@ -32,7 +32,7 @@
 #define DEBUG_SUBSYSTEM S_LOV
 
 #include <libcfs/libcfs.h>
-
+#include <cl_object.h>
 #include <obd_class.h>
 #include "lov_internal.h"
 
  * uptodate time on the local client.
  */
 int lov_merge_lvb_kms(struct lov_stripe_md *lsm, int index,
-                     struct ost_lvb *lvb, __u64 *kms_place)
+                     struct cl_attr *attr)
 {
        struct lov_stripe_md_entry *lse = lsm->lsm_entries[index];
        u64 size = 0;
        u64 kms = 0;
        u64 blocks = 0;
-       s64 current_mtime = lvb->lvb_mtime;
-       s64 current_atime = lvb->lvb_atime;
-       s64 current_ctime = lvb->lvb_ctime;
+       /* XXX: timestamps can be negative by sanity:test_39m,
+        * how can it be? */
+       s64 current_mtime = LLONG_MIN;
+       s64 current_atime = LLONG_MIN;
+       s64 current_ctime = LLONG_MIN;
        int i;
        int rc = 0;
 
        assert_spin_locked(&lsm->lsm_lock);
        LASSERT(lsm->lsm_lock_owner == current->pid);
-
-       CDEBUG(D_INODE, "MDT ID "DOSTID" initial value: s=%llu m=%llu"
-              " a=%llu c=%llu b=%llu\n", POSTID(&lsm->lsm_oi),
-              lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime,
-              lvb->lvb_blocks);
        for (i = 0; i < lse->lsme_stripe_count; i++) {
                struct lov_oinfo *loi = lse->lsme_oinfo[i];
                u64 lov_size;
@@ -71,7 +68,12 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, int index,
                        continue;
                }
 
-               tmpsize = loi->loi_kms;
+               if (loi->loi_kms_valid) {
+                       attr->cat_kms_valid = 1;
+                       tmpsize = loi->loi_kms;
+               } else {
+                       tmpsize = 0;
+               }
                lov_size = lov_stripe_size(lsm, index, tmpsize, i);
                if (lov_size > kms)
                        kms = lov_size;
@@ -91,18 +93,20 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, int index,
                if (loi->loi_lvb.lvb_ctime > current_ctime)
                        current_ctime = loi->loi_lvb.lvb_ctime;
 
-               CDEBUG(D_INODE, "MDT ID "DOSTID" on OST[%u]: s=%llu m=%llu"
+               CDEBUG(D_INODE, "MDT ID "DOSTID" on OST[%u]: s=%llu (%d) m=%llu"
                       " a=%llu c=%llu b=%llu\n", POSTID(&lsm->lsm_oi),
-                      loi->loi_ost_idx, loi->loi_lvb.lvb_size,
+                      loi->loi_ost_idx, loi->loi_lvb.lvb_size, loi->loi_kms_valid,
                       loi->loi_lvb.lvb_mtime, loi->loi_lvb.lvb_atime,
                       loi->loi_lvb.lvb_ctime, loi->loi_lvb.lvb_blocks);
        }
 
-       *kms_place = kms;
-       lvb->lvb_size = size;
-       lvb->lvb_blocks = blocks;
-       lvb->lvb_mtime = current_mtime;
-       lvb->lvb_atime = current_atime;
-       lvb->lvb_ctime = current_ctime;
+       if (!rc) {
+               attr->cat_kms    = kms;
+               attr->cat_size   = size;
+               attr->cat_mtime  = current_mtime;
+               attr->cat_atime  = current_atime;
+               attr->cat_ctime  = current_ctime;
+               attr->cat_blocks = blocks;
+       }
        RETURN(rc);
 }
index 5ae9e5a..ed35015 100644 (file)
@@ -372,9 +372,7 @@ static int lov_attr_get_raid0(const struct lu_env *env, struct lov_object *lov,
 {
        struct lov_layout_raid0 *r0 = &lle->lle_raid0;
        struct lov_stripe_md *lsm = lov->lo_lsm;
-       struct ost_lvb *lvb = &lov_env_info(env)->lti_lvb;
        struct cl_attr *attr = &r0->lo_attr;
-       __u64 kms = 0;
        int result = 0;
 
        if (r0->lo_attr_valid) {
@@ -382,20 +380,6 @@ static int lov_attr_get_raid0(const struct lu_env *env, struct lov_object *lov,
                return 0;
        }
 
-       memset(lvb, 0, sizeof(*lvb));
-
-       /* XXX: timestamps can be negative by sanity:test_39m,
-        * how can it be? */
-       lvb->lvb_atime = LLONG_MIN;
-       lvb->lvb_ctime = LLONG_MIN;
-       lvb->lvb_mtime = LLONG_MIN;
-
-       /*
-        * XXX that should be replaced with a loop over sub-objects,
-        * doing cl_object_attr_get() on them. But for now, let's
-        * reuse old lov code.
-        */
-
        /*
         * XXX take lsm spin-lock to keep lov_merge_lvb_kms()
         * happy. It's not needed, because new code uses
@@ -403,11 +387,9 @@ static int lov_attr_get_raid0(const struct lu_env *env, struct lov_object *lov,
         * sub-object attributes.
         */
        lov_stripe_lock(lsm);
-       result = lov_merge_lvb_kms(lsm, index, lvb, &kms);
+       result = lov_merge_lvb_kms(lsm, index, attr);
        lov_stripe_unlock(lsm);
        if (result == 0) {
-               cl_lvb2attr(attr, lvb);
-               attr->cat_kms = kms;
                r0->lo_attr_valid = 1;
                *lov_attr = attr;
        }
@@ -1052,6 +1034,8 @@ static int lov_attr_get_composite(const struct lu_env *env,
                       lov_attr->cat_ctime, lov_attr->cat_blocks);
 
                /* merge results */
+               if (lov_attr->cat_kms_valid)
+                       attr->cat_kms_valid = 1;
                attr->cat_blocks += lov_attr->cat_blocks;
                if (attr->cat_size < lov_attr->cat_size)
                        attr->cat_size = lov_attr->cat_size;
index a4a1aee..4d2aec1 100755 (executable)
@@ -10612,7 +10612,7 @@ ra_check_101() {
 
        if [[ $discard -gt $discard_limit ]]; then
                $LCTL get_param llite.*.read_ahead_stats
-               error "($discard) discarded pages with size (${read_size})"
+               error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
        else
                echo "Read-ahead success for size ${read_size}"
        fi
@@ -25023,6 +25023,11 @@ test_398n() { #  LU-13798
 }
 run_test 398n "test append with parallel DIO"
 
+test_398o() {
+       directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
+}
+run_test 398o "right kms with DIO"
+
 test_fake_rw() {
        local read_write=$1
        if [ "$read_write" = "write" ]; then
index 05c53a0..7046666 100755 (executable)
@@ -6930,6 +6930,10 @@ run_one_logged() {
                fi
 
                pass "$testnum" "(${duration_sub}s)"
+               if [ -n "${DUMP_OK}" ]; then
+                       gather_logs $(comma_list $(nodes_list))
+               fi
+
                log_sub_test_end $TEST_STATUS $duration_sub "$rc" "$test_error"
                [[ $rc != 0 ]] && break
        done