]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: do not assert on non-zero err codes from compress() call 26342/head
authorIgor Fedotov <ifedotov@suse.com>
Thu, 10 Jan 2019 09:58:05 +0000 (12:58 +0300)
committerIgor Fedotov <ifedotov@suse.com>
Fri, 8 Feb 2019 17:17:48 +0000 (20:17 +0300)
Fixes: https://tracker.ceph.com/issues/37839
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
(cherry picked from commit 4083bc29b6b4191a5ef3c17976eeac091626f1b0)

src/os/bluestore/BlueStore.cc

index 6604cee61e5f75ccffecb33b1fe589f1938109e4..a5c440fc2a1f0eafebdbc42b933e73fef138ff67 100644 (file)
@@ -10811,36 +10811,57 @@ int BlueStore::_do_alloc_write(
       // FIXME: memory alignment here is bad
       bufferlist t;
       int r = c->compress(wi.bl, t);
-      ceph_assert(r == 0);
-
-      bluestore_compression_header_t chdr;
-      chdr.type = c->get_type();
-      chdr.length = t.length();
-      encode(chdr, wi.compressed_bl);
-      wi.compressed_bl.claim_append(t);
-
-      wi.compressed_len = wi.compressed_bl.length();
-      uint64_t newlen = p2roundup(wi.compressed_len, min_alloc_size);
       uint64_t want_len_raw = wi.blob_length * crr;
       uint64_t want_len = p2roundup(want_len_raw, min_alloc_size);
-      if (newlen <= want_len && newlen < wi.blob_length) {
-       // Cool. We compressed at least as much as we were hoping to.
-       // pad out to min_alloc_size
-       wi.compressed_bl.append_zero(newlen - wi.compressed_len);
-       logger->inc(l_bluestore_write_pad_bytes, newlen - wi.compressed_len);
-       dout(20) << __func__ << std::hex << "  compressed 0x" << wi.blob_length
-                << " -> 0x" << wi.compressed_len << " => 0x" << newlen
-                << " with " << c->get_type()
-                << std::dec << dendl;
-       txc->statfs_delta.compressed() += wi.compressed_len;
-       txc->statfs_delta.compressed_original() += wi.blob_length;
-       txc->statfs_delta.compressed_allocated() += newlen;
-       logger->inc(l_bluestore_compress_success_count);
-       wi.compressed = true;
-       need += newlen;
+      bool rejected = false;
+      uint64_t compressed_len = t.length();
+      // do an approximate (fast) estimation for resulting blob size
+      // that doesn't take header overhead  into account
+      uint64_t result_len = p2roundup(compressed_len, min_alloc_size);
+      if (r == 0 && result_len <= want_len && result_len < wi.blob_length) {
+       bluestore_compression_header_t chdr;
+       chdr.type = c->get_type();
+       chdr.length = t.length();
+       encode(chdr, wi.compressed_bl);
+       wi.compressed_bl.claim_append(t);
+
+       compressed_len = wi.compressed_bl.length();
+       result_len = p2roundup(compressed_len, min_alloc_size);
+       if (result_len <= want_len && result_len < wi.blob_length) {
+         // Cool. We compressed at least as much as we were hoping to.
+         // pad out to min_alloc_size
+         wi.compressed_bl.append_zero(result_len - compressed_len);
+         wi.compressed_len = compressed_len;
+         wi.compressed = true;
+         logger->inc(l_bluestore_write_pad_bytes, result_len - compressed_len);
+         dout(20) << __func__ << std::hex << "  compressed 0x" << wi.blob_length
+                  << " -> 0x" << compressed_len << " => 0x" << result_len
+                  << " with " << c->get_type()
+                  << std::dec << dendl;
+         txc->statfs_delta.compressed() += compressed_len;
+         txc->statfs_delta.compressed_original() += wi.blob_length;
+         txc->statfs_delta.compressed_allocated() += result_len;
+         logger->inc(l_bluestore_compress_success_count);
+         need += result_len;
+       } else {
+         rejected = true;
+       }
+      } else if (r != 0) {
+       dout(5) << __func__ << std::hex << "  0x" << wi.blob_length
+                << " bytes compressed using " << c->get_type_name()
+                << std::dec
+                << " failed with errcode = " << r
+                << ", leaving uncompressed"
+                << dendl;
+       logger->inc(l_bluestore_compress_rejected_count);
+       need += wi.blob_length;
       } else {
+       rejected = true;
+      }
+
+      if (rejected) {
        dout(20) << __func__ << std::hex << "  0x" << wi.blob_length
-                << " compressed to 0x" << wi.compressed_len << " -> 0x" << newlen
+                << " compressed to 0x" << compressed_len << " -> 0x" << result_len
                 << " with " << c->get_type()
                 << ", which is more than required 0x" << want_len_raw
                 << " -> 0x" << want_len