Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp1129541ybt; Wed, 24 Jun 2020 21:17:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxEmCgfSf13BhffiIlurppOvcxcqZli5uxW445Fn+JNXEsBEVh6k2MwftIIKY8jGf51ZD+h X-Received: by 2002:a17:906:abca:: with SMTP id kq10mr27172172ejb.242.1593058657139; Wed, 24 Jun 2020 21:17:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1593058657; cv=none; d=google.com; s=arc-20160816; b=pSHy1dPNqjmv6mbrtSxbaS9znPi0utJiJ0Pl9juMQO6H/4kG5LK3YboD//nyN5ETRD fmmbGYgPMFaIOHxMbIFxBDtnb3sb+VRlTcxiD/Dvi6RhrOobRYw9dapKj4aVkqVuOQn5 5sjHFrpg6ZMMv6r/vOf5uPyweluLT/kC5A9URnzm9GFR19IlrytsDQ4KJQx2UyV7114+ J5X1bl1wogF6mnTx6sKx7u8v0hhE+MN4tyC3qLPFFjMoDxKJe1mkj/J0Kc5tXwqu9d2k d5B04gBehpP56rsaUk7zaFTtPOna+OASxFTJ6lOx6uZin9nOPsF2yF3ctXIeDPairZdX J3Uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=wj3e8MR4iLmW0dzt7Hoey3yyBzaM6hHCOrqtS8FFnKI=; b=Gl0KN10gVNYDSdTIY4cTdiqwyGTcAcytYbMFKP7bZXNLXJctq/jP+PCnI4IauL+u17 v7ZsnwelNoeLjteZa9rj3P/lZfi6tiOvKDxqgIcGwG6+9vTNWJfR64YdH7JziiCVB290 dtQ3hJrMzwa/ny23DeY12+tZLB1HAwYCy7Ed3uL9LvgHeECyw6GYJGW8oJlgxOEEKdFY cf98oeBpQhCD3M/iz03AZOFhFdni8J8ndIoh6p8B/PPrl3JdEyj3AkpcgcX73eOZ/mww hmwKIAHoIz5nYartyty29IDwql8GdzfjFGU+So+o7kQol1Zm9WGffkCsgWkLkJcoU0YF MgXg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cc13si5213272edb.297.2020.06.24.21.17.13; Wed, 24 Jun 2020 21:17:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726914AbgFYEMj (ORCPT + 99 others); Thu, 25 Jun 2020 00:12:39 -0400 Received: from out20-26.mail.aliyun.com ([115.124.20.26]:41484 "EHLO out20-26.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726732AbgFYEMj (ORCPT ); Thu, 25 Jun 2020 00:12:39 -0400 X-Alimail-AntiSpam: AC=CONTINUE;BC=0.07436282|-1;CH=green;DM=|CONTINUE|false|;DS=CONTINUE|ham_system_inform|0.0910485-0.000687189-0.908264;FP=10108297775467472176|1|1|1|0|-1|-1|-1;HT=e02c03294;MF=aiden.leong@aibsd.com;NM=1;PH=DS;RN=12;RT=12;SR=0;TI=SMTPD_---.Hs8KRsM_1593058336; Received: from ubuntu(mailfrom:aiden.leong@aibsd.com fp:SMTPD_---.Hs8KRsM_1593058336) by smtp.aliyun-inc.com(10.147.43.95); Thu, 25 Jun 2020 12:12:32 +0800 From: Aiden Leong To: "Gustavo A. R. Silva" , Thomas Gleixner , Ferdinand Blomqvist , YueHaibing , dm-devel@redhat.com, linux-kernel@vger.kernel.org Cc: Alasdair Kergon , Mike Snitzer , Kees Cook , Anton Vorontsov , Colin Cross , Tony Luck Subject: [RFC] Reed-Solomon Code: Update no_eras to the actual number of errors Date: Wed, 24 Jun 2020 21:10:53 -0700 Message-Id: <20200625041141.8053-1-aiden.leong@aibsd.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Corr and eras_pos are updated to actual correction pattern and erasure positions, but no_eras is not. When this library is used to recover lost bytes, we normally memset the lost trunk of bytes to zero as a placeholder. Unfortunately, if the lost byte is zero, b[i] is zero too. Without correct no_eras, users won't be able to determine the valid length of corr and eras_pos. Signed-off-by: Aiden Leong --- drivers/md/dm-verity-fec.c | 2 +- fs/pstore/ram_core.c | 2 +- include/linux/rslib.h | 4 ++-- lib/reed_solomon/decode_rs.c | 20 ++++++++++++++------ lib/reed_solomon/reed_solomon.c | 4 ++-- lib/reed_solomon/test_rslib.c | 18 ++++++++++++------ 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c index fb41b4f23c48..ae8366a50244 100644 --- a/drivers/md/dm-verity-fec.c +++ b/drivers/md/dm-verity-fec.c @@ -50,7 +50,7 @@ static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio, for (i = 0; i < v->fec->roots; i++) par[i] = fec[i]; - return decode_rs8(fio->rs, data, par, v->fec->rsn, NULL, neras, + return decode_rs8(fio->rs, data, par, v->fec->rsn, NULL, &neras, fio->erasures, 0, NULL); } diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index aa8e0b65ff1a..fcc661a60640 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -115,7 +115,7 @@ static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz, for (i = 0; i < prz->ecc_info.ecc_size; i++) prz->ecc_info.par[i] = ecc[i]; - return decode_rs8(prz->rs_decoder, data, prz->ecc_info.par, len, + return decode_rs8(prz->rs_decoder, data, prz->ecc_info.par, &len, NULL, 0, NULL, 0, NULL); } diff --git a/include/linux/rslib.h b/include/linux/rslib.h index 238bb85243d3..80662abc9af7 100644 --- a/include/linux/rslib.h +++ b/include/linux/rslib.h @@ -64,7 +64,7 @@ int encode_rs8(struct rs_control *rs, uint8_t *data, int len, uint16_t *par, #endif #ifdef CONFIG_REED_SOLOMON_DEC8 int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len, - uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, + uint16_t *s, int *no_eras, int *eras_pos, uint16_t invmsk, uint16_t *corr); #endif @@ -75,7 +75,7 @@ int encode_rs16(struct rs_control *rs, uint16_t *data, int len, uint16_t *par, #endif #ifdef CONFIG_REED_SOLOMON_DEC16 int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len, - uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, + uint16_t *s, int *no_eras, int *eras_pos, uint16_t invmsk, uint16_t *corr); #endif diff --git a/lib/reed_solomon/decode_rs.c b/lib/reed_solomon/decode_rs.c index 805de84ae83d..122bc08eb75f 100644 --- a/lib/reed_solomon/decode_rs.c +++ b/lib/reed_solomon/decode_rs.c @@ -24,6 +24,7 @@ int count = 0; int num_corrected; uint16_t msk = (uint16_t) rs->nn; + int no_eras_orig = no_eras ? *no_eras : 0; /* * The decoder buffers are in the rs control struct. They are @@ -106,11 +107,11 @@ memset(&lambda[1], 0, nroots * sizeof(lambda[0])); lambda[0] = 1; - if (no_eras > 0) { + if (no_eras_orig > 0) { /* Init lambda to be the erasure locator polynomial */ lambda[1] = alpha_to[rs_modnn(rs, prim * (nn - 1 - (eras_pos[0] + pad)))]; - for (i = 1; i < no_eras; i++) { + for (i = 1; i < no_eras_orig; i++) { u = rs_modnn(rs, prim * (nn - 1 - (eras_pos[i] + pad))); for (j = i + 1; j > 0; j--) { tmp = index_of[lambda[j - 1]]; @@ -129,8 +130,8 @@ * Begin Berlekamp-Massey algorithm to determine error+erasure * locator polynomial */ - r = no_eras; - el = no_eras; + r = no_eras_orig; + el = no_eras_orig; while (++r <= nroots) { /* r is the step number */ /* Compute discrepancy at the r-th step in poly-form */ discr_r = 0; @@ -158,8 +159,8 @@ } else t[i + 1] = lambda[i + 1]; } - if (2 * el <= r + no_eras - 1) { - el = r + no_eras - el; + if (2 * el <= r + no_eras_orig - 1) { + el = r + no_eras_orig - el; /* * 2 lines below: B(x) <-- inv(discr_r) * * lambda(x) @@ -312,14 +313,21 @@ eras_pos[j++] = loc[i] - pad; } } + if (no_eras > 0) + *no_eras = j; } else if (data && par) { /* Apply error to data and parity */ + j = 0; for (i = 0; i < count; i++) { if (loc[i] < (nn - nroots)) data[loc[i] - pad] ^= b[i]; else par[loc[i] - pad - len] ^= b[i]; + if (b[i]) + j++; } + if (no_eras > 0) + *no_eras = j; } return num_corrected; diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c index bbc01bad3053..b2c811674c98 100644 --- a/lib/reed_solomon/reed_solomon.c +++ b/lib/reed_solomon/reed_solomon.c @@ -359,7 +359,7 @@ EXPORT_SYMBOL_GPL(encode_rs8); * errors. The count includes errors in the parity. */ int decode_rs8(struct rs_control *rsc, uint8_t *data, uint16_t *par, int len, - uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, + uint16_t *s, int *no_eras, int *eras_pos, uint16_t invmsk, uint16_t *corr) { #include "decode_rs.c" @@ -410,7 +410,7 @@ EXPORT_SYMBOL_GPL(encode_rs16); * errors. The count includes errors in the parity. */ int decode_rs16(struct rs_control *rsc, uint16_t *data, uint16_t *par, int len, - uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk, + uint16_t *s, int *no_eras, int *eras_pos, uint16_t invmsk, uint16_t *corr) { #include "decode_rs.c" diff --git a/lib/reed_solomon/test_rslib.c b/lib/reed_solomon/test_rslib.c index 4eb29f365ece..b30a4aea8796 100644 --- a/lib/reed_solomon/test_rslib.c +++ b/lib/reed_solomon/test_rslib.c @@ -258,7 +258,7 @@ static void compute_syndrome(struct rs_control *rsc, uint16_t *data, /* Test up to error correction capacity */ static void test_uc(struct rs_control *rs, int len, int errs, - int eras, int trials, struct estat *stat, + int *eras, int trials, struct estat *stat, struct wspace *ws, int method) { int dlen = len - rs->codec->nroots; @@ -327,8 +327,11 @@ static int ex_rs_helper(struct rs_control *rs, struct wspace *ws, pr_info(" %s\n", desc[method]); for (errs = 0; errs <= nroots / 2; errs++) - for (eras = 0; eras <= nroots - 2 * errs; eras++) - test_uc(rs, len, errs, eras, trials, &stat, ws, method); + for (eras = 0; eras <= nroots - 2 * errs; eras++) { + int no_eras = ers; + + test_uc(rs, len, errs, &no_eras, trials, &stat, ws, method); + } if (v >= V_CSUMMARY) { pr_info(" Decodes wrong: %d / %d\n", @@ -364,7 +367,7 @@ static int exercise_rs(struct rs_control *rs, struct wspace *ws, /* Tests for correct behaviour beyond error correction capacity */ static void test_bc(struct rs_control *rs, int len, int errs, - int eras, int trials, struct bcstat *stat, + int *eras, int trials, struct bcstat *stat, struct wspace *ws) { int nroots = rs->codec->nroots; @@ -420,8 +423,11 @@ static int exercise_rs_bc(struct rs_control *rs, struct wspace *ws, eras = 0; cutoff = nroots <= len - errs ? nroots : len - errs; - for (; eras <= cutoff; eras++) - test_bc(rs, len, errs, eras, trials, &stat, ws); + for (; eras <= cutoff; eras++) { + int no_eras = eras; + + test_bc(rs, len, errs, &no_eras, trials, &stat, ws); + } } if (v >= V_CSUMMARY) { -- 2.25.1