OSDN Git Service

Remove canned_fs_config from ext4_utils
[android-x86/system-extras.git] / libfec / fec_read.cpp
index 68ea410..2d29da8 100644 (file)
@@ -77,7 +77,7 @@ static inline bool is_erasure(fec_handle *f, uint64_t offset,
 
     uint64_t n = offset / FEC_BLOCKSIZE;
 
-    return !verity_check_block(f, n, &f->verity.hash[n * SHA256_DIGEST_LENGTH],
+    return !verity_check_block(f, &f->verity.hash[n * SHA256_DIGEST_LENGTH],
                 data);
 }
 
@@ -127,20 +127,21 @@ static int __ecc_read(fec_handle *f, void *rs, uint8_t *dest, uint64_t offset,
             data_index = i;
         }
 
-        /* copy raw data to reconstruct the RS block */
-        uint8_t bbuf[FEC_BLOCKSIZE];
+        /* to improve our chances of correcting IO errors, initialize the
+           buffer to zeros even if we are going to read to it later */
+        uint8_t bbuf[FEC_BLOCKSIZE] = {0};
 
-        if (unlikely(interleaved >= e->start) ||
-                is_zero(f, interleaved)) {
-            memset(bbuf, 0, FEC_BLOCKSIZE);
-        } else {
+        if (likely(interleaved < e->start) && !is_zero(f, interleaved)) {
+            /* copy raw data to reconstruct the RS block */
             if (!raw_pread(f, bbuf, FEC_BLOCKSIZE, interleaved)) {
-                error("failed to read: %s", strerror(errno));
-                return -1;
-            }
+                warn("failed to read: %s", strerror(errno));
 
-            if (use_erasures && neras <= e->roots &&
-                    is_erasure(f, interleaved, bbuf)) {
+                /* treat errors as corruption */
+                if (use_erasures && neras <= e->roots) {
+                    erasures[neras++] = i;
+                }
+            } else if (use_erasures && neras <= e->roots &&
+                            is_erasure(f, interleaved, bbuf)) {
                 erasures[neras++] = i;
             }
         }
@@ -327,7 +328,7 @@ static ssize_t verity_read(fec_handle *f, uint8_t *dest, size_t count,
             return -1;
         }
 
-        if (likely(verity_check_block(f, curr, hash, data))) {
+        if (likely(verity_check_block(f, hash, data))) {
             goto valid;
         }
 
@@ -352,14 +353,14 @@ static ssize_t verity_read(fec_handle *f, uint8_t *dest, size_t count,
            erasure locations is slower */
         if (__ecc_read(f, rs.get(), data, curr_offset, false, ecc_data.get(),
                 errors) == FEC_BLOCKSIZE &&
-            verity_check_block(f, VERITY_NO_CACHE, hash, data)) {
+            verity_check_block(f, hash, data)) {
             goto corrected;
         }
 
         /* try to correct with erasures */
         if (__ecc_read(f, rs.get(), data, curr_offset, true, ecc_data.get(),
                 errors) == FEC_BLOCKSIZE &&
-            verity_check_block(f, VERITY_NO_CACHE, hash, data)) {
+            verity_check_block(f, hash, data)) {
             goto corrected;
         }