]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
bug fix: osd: do not cache unused buffer in attrs 5451/head
authorXinze Chi <xmdxcxz@gmail.com>
Sun, 2 Aug 2015 10:36:40 +0000 (18:36 +0800)
committerXinze Chi <xmdxcxz@gmail.com>
Mon, 24 Aug 2015 14:31:55 +0000 (22:31 +0800)
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>
src/osd/ECBackend.cc
src/osd/ReplicatedBackend.cc

index 47f326efaf17679b3b08f5156b2ee4908cf9d9a4..0899bc86c1c82ebb9dc9eefc8f87472be0c771cb 100644 (file)
@@ -372,6 +372,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 5ddc9fd311efce061cc5109525e367fafe077411..e1cf238b2b42a7db0bacda9aa7b4da265e794f77 100644 (file)
@@ -1811,6 +1811,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);