From dc907414db16d99e77aecf6bfd41d82b8cf7c36e Mon Sep 17 00:00:00 2001 From: Alexey Lyashkov Date: Thu, 19 May 2022 20:35:18 +0300 Subject: [PATCH] LU-15829 llite: don't use a kms if it invalid. 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 Change-Id: Ie71d3f3cc24fc16c03ed07f9f5a3a17c7fdfa684 Reviewed-on: https://review.whamcloud.com/47395 Reviewed-by: Shaun Tancheff Tested-by: jenkins Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/include/cl_object.h | 2 ++ lustre/llite/vvp_io.c | 2 +- lustre/lov/lov_internal.h | 2 +- lustre/lov/lov_merge.c | 42 +++++++++++++++++++++++------------------- lustre/lov/lov_object.c | 22 +++------------------- lustre/tests/sanity.sh | 7 ++++++- lustre/tests/test-framework.sh | 4 ++++ 7 files changed, 40 insertions(+), 41 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 2ef9c84..bc534e0 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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. * diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index 9ae65ac..5701737 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -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 diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index 9341d2e..9e82077 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -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); diff --git a/lustre/lov/lov_merge.c b/lustre/lov/lov_merge.c index 30fb5b4..09d2299 100644 --- a/lustre/lov/lov_merge.c +++ b/lustre/lov/lov_merge.c @@ -32,7 +32,7 @@ #define DEBUG_SUBSYSTEM S_LOV #include - +#include #include #include "lov_internal.h" @@ -42,25 +42,22 @@ * 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); } diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 5ae9e5a..ed35015 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -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; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index a4a1aee..4d2aec1 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 05c53a0..7046666 100755 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -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 -- 1.8.3.1