]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
bug fix: osd: do not cache unused buffer in attrs 6499/head
authorXinze Chi <xmdxcxz@gmail.com>
Sun, 2 Aug 2015 10:36:40 +0000 (18:36 +0800)
committerNathan Cutler <ncutler@suse.com>
Mon, 9 Nov 2015 09:47:48 +0000 (10:47 +0100)
attrs only reference the origin bufferlist (decode from MOSDPGPush or
ECSubReadReply message) whose size is much greater than attrs in recovery.
If obc cache it (get_obc maybe cache the attr), this causes the whole origin
bufferlist would not be free until obc is evicted from obc cache. So rebuild
the bufferlist before cache it.

Fixes: #12565
Signed-off-by: Ning Yao <zay11022@gmail.com>
Signed-off-by: Xinze Chi <xmdxcxz@gmail.com>
(cherry picked from commit c5895d3fad9da0ab7f05f134c49e22795d5c61f3)

src/osd/ECBackend.cc
src/osd/ReplicatedBackend.cc

index 845ea832eeb80e9a0dba9d7d925f0e8397b75886..3b517402bcef79943953ceb1208e6a02e8766110 100644 (file)
@@ -366,6 +366,15 @@ void ECBackend::handle_recovery_read_complete(
     op.xattrs.swap(*attrs);
 
     if (!op.obc) {
+      // attrs only reference the origin bufferlist (decode from ECSubReadReply message)
+      // whose size is much greater than attrs in recovery. If obc cache it (get_obc maybe
+      // cache the attr), this causes the whole origin bufferlist would not be free until
+      // obc is evicted from obc cache. So rebuild the bufferlist before cache it.
+      for (map<string, bufferlist>::iterator it = op.xattrs.begin();
+           it != op.xattrs.end();
+           ++it) {
+        it->second.rebuild();
+      }
       op.obc = get_parent()->get_obc(hoid, op.xattrs);
       op.recovery_info.size = op.obc->obs.oi.size;
       op.recovery_info.oi = op.obc->obs.oi;
index b86d4d1e7444f1661af0604e0f2804eb02160b0f..7dab73c86ecf3e3274ff2280b338253c002c320a 100644 (file)
@@ -1802,6 +1802,15 @@ bool ReplicatedBackend::handle_pull_response(
 
   bool first = pi.recovery_progress.first;
   if (first) {
+    // attrs only reference the origin bufferlist (decode from MOSDPGPush message)
+    // whose size is much greater than attrs in recovery. If obc cache it (get_obc maybe
+    // cache the attr), this causes the whole origin bufferlist would not be free until
+    // obc is evicted from obc cache. So rebuild the bufferlist before cache it.
+    for (map<string, bufferlist>::iterator it = pop.attrset.begin();
+         it != pop.attrset.end();
+         ++it) {
+      it->second.rebuild();
+    }
     pi.obc = get_parent()->get_obc(pi.recovery_info.soid, pop.attrset);
     pi.recovery_info.oi = pi.obc->obs.oi;
     pi.recovery_info = recalc_subsets(pi.recovery_info, pi.obc->ssc);