This is a simple performance refactor.
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
 
 #include "include/buffer.h"
 #include "common/Formatter.h"
+#include "common/StackStringStream.h"
 #include "common/ceph_time.h"
 
 #include <cmath>
 }
 
 inline std::ostream& operator<<(std::ostream& out, const DecayCounter& d) {
-  std::ostringstream oss;
-  oss.precision(2);
+  CachedStackStringStream css;
+  css->precision(2);
   double val = d.get();
-  oss << "[C " << std::scientific << val << "]";
-  return out << oss.str();
+  *css << "[C " << std::scientific << val << "]";
+  return out << css->strv();
 }
 
 #endif
 
   std::string_view strv() const {
     return ssb.strv();
   }
+  std::string str() const {
+    return std::string(ssb.strv());
+  }
 
 private:
   StackStringBuf<SIZE> ssb;
 
  * false, ss is valid */
 
 bool
-cmdmap_from_json(const vector<string>& cmd, cmdmap_t *mapp, stringstream &ss)
+cmdmap_from_json(const vector<string>& cmd, cmdmap_t *mapp, std::ostream& ss)
 {
   json_spirit::mValue v;
 
 
                          const std::string& perm,
                          uint64_t flags);
 bool cmdmap_from_json(const std::vector<std::string>& cmd, cmdmap_t *mapp,
-                     std::stringstream &ss);
+                     std::ostream& ss);
 void cmdmap_dump(const cmdmap_t &cmdmap, ceph::Formatter *f);
 void handle_bad_get(CephContext *cct, const std::string& k, const char *name);
 
 
   // Indicates MDS is not trimming promptly
   {
     if (mds->mdlog->get_num_segments() > (size_t)(g_conf()->mds_log_max_segments * g_conf().get_val<double>("mds_log_warn_factor"))) {
-      std::ostringstream oss;
-      oss << "Behind on trimming (" << mds->mdlog->get_num_segments()
+      CachedStackStringStream css;
+      *css << "Behind on trimming (" << mds->mdlog->get_num_segments()
         << "/" << g_conf()->mds_log_max_segments << ")";
 
-      MDSHealthMetric m(MDS_HEALTH_TRIM, HEALTH_WARN, oss.str());
+      MDSHealthMetric m(MDS_HEALTH_TRIM, HEALTH_WARN, css->strv());
       m.metadata["num_segments"] = stringify(mds->mdlog->get_num_segments());
       m.metadata["max_segments"] = stringify(g_conf()->mds_log_max_segments);
       health.metrics.push_back(m);
         continue;
       }
 
-      std::ostringstream oss;
-      oss << "Client " << s->get_human_name() << " failing to respond to capability release";
-      MDSHealthMetric m(MDS_HEALTH_CLIENT_LATE_RELEASE, HEALTH_WARN, oss.str());
+      CachedStackStringStream css;
+      *css << "Client " << s->get_human_name() << " failing to respond to capability release";
+      MDSHealthMetric m(MDS_HEALTH_CLIENT_LATE_RELEASE, HEALTH_WARN, css->strv());
       m.metadata["client_id"] = stringify(client.v);
       late_cap_metrics.emplace_back(std::move(m));
     }
       auto&& m = late_cap_metrics;
       health.metrics.insert(std::end(health.metrics), std::cbegin(m), std::cend(m));
     } else {
-      std::ostringstream oss;
-      oss << "Many clients (" << late_cap_metrics.size()
+      CachedStackStringStream css;
+      *css << "Many clients (" << late_cap_metrics.size()
           << ") failing to respond to capability release";
-      MDSHealthMetric m(MDS_HEALTH_CLIENT_LATE_RELEASE_MANY, HEALTH_WARN, oss.str());
+      MDSHealthMetric m(MDS_HEALTH_CLIENT_LATE_RELEASE_MANY, HEALTH_WARN, css->strv());
       m.metadata["client_count"] = stringify(late_cap_metrics.size());
       health.metrics.push_back(std::move(m));
     }
         dout(2) << "Session " << *session <<
              " is not releasing caps fast enough. Recalled caps at " << recall_caps
           << " > " << recall_warning_threshold << " (mds_recall_warning_threshold)." << dendl;
-        std::ostringstream oss;
-        oss << "Client " << session->get_human_name() << " failing to respond to cache pressure";
-        MDSHealthMetric m(MDS_HEALTH_CLIENT_RECALL, HEALTH_WARN, oss.str());
+        CachedStackStringStream css;
+        *css << "Client " << session->get_human_name() << " failing to respond to cache pressure";
+        MDSHealthMetric m(MDS_HEALTH_CLIENT_RECALL, HEALTH_WARN, css->strv());
         m.metadata["client_id"] = stringify(session->get_client());
         late_recall_metrics.emplace_back(std::move(m));
       }
           session->get_num_completed_requests() >= max_completed_requests) ||
          (session->get_num_trim_flushes_warnings() > 0 &&
           session->get_num_completed_flushes() >= max_completed_flushes)) {
-       std::ostringstream oss;
-       oss << "Client " << session->get_human_name() << " failing to advance its oldest client/flush tid. ";
-       MDSHealthMetric m(MDS_HEALTH_CLIENT_OLDEST_TID, HEALTH_WARN, oss.str());
+       CachedStackStringStream css;
+       *css << "Client " << session->get_human_name() << " failing to advance its oldest client/flush tid. ";
+       MDSHealthMetric m(MDS_HEALTH_CLIENT_OLDEST_TID, HEALTH_WARN, css->strv());
        m.metadata["client_id"] = stringify(session->get_client());
        large_completed_requests_metrics.emplace_back(std::move(m));
       }
       auto&& m = late_recall_metrics;
       health.metrics.insert(std::end(health.metrics), std::cbegin(m), std::cend(m));
     } else {
-      std::ostringstream oss;
-      oss << "Many clients (" << late_recall_metrics.size()
+      CachedStackStringStream css;
+      *css << "Many clients (" << late_recall_metrics.size()
           << ") failing to respond to cache pressure";
-      MDSHealthMetric m(MDS_HEALTH_CLIENT_RECALL_MANY, HEALTH_WARN, oss.str());
+      MDSHealthMetric m(MDS_HEALTH_CLIENT_RECALL_MANY, HEALTH_WARN, css->strv());
       m.metadata["client_count"] = stringify(late_recall_metrics.size());
       health.metrics.push_back(m);
       late_recall_metrics.clear();
       auto&& m = large_completed_requests_metrics;
       health.metrics.insert(std::end(health.metrics), std::cbegin(m), std::cend(m));
     } else {
-      std::ostringstream oss;
-      oss << "Many clients (" << large_completed_requests_metrics.size()
+      CachedStackStringStream css;
+      *css << "Many clients (" << large_completed_requests_metrics.size()
        << ") failing to advance their oldest client/flush tid";
-      MDSHealthMetric m(MDS_HEALTH_CLIENT_OLDEST_TID_MANY, HEALTH_WARN, oss.str());
+      MDSHealthMetric m(MDS_HEALTH_CLIENT_OLDEST_TID_MANY, HEALTH_WARN, css->strv());
       m.metadata["client_count"] = stringify(large_completed_requests_metrics.size());
       health.metrics.push_back(m);
       large_completed_requests_metrics.clear();
     int slow = mds->get_mds_slow_req_count();
     if (slow) {
       dout(20) << slow << " slow request found" << dendl;
-      std::ostringstream oss;
-      oss << slow << " slow requests are blocked > " << g_conf()->mds_op_complaint_time << " secs";
+      CachedStackStringStream css;
+      *css << slow << " slow requests are blocked > " << g_conf()->mds_op_complaint_time << " secs";
 
-      MDSHealthMetric m(MDS_HEALTH_SLOW_REQUEST, HEALTH_WARN, oss.str());
+      MDSHealthMetric m(MDS_HEALTH_SLOW_REQUEST, HEALTH_WARN, css->strv());
       health.metrics.push_back(m);
     }
   }
       dout(20) << count << " slow metadata IOs found" << dendl;
 
       auto oldest_secs = std::chrono::duration<double>(now - oldest).count();
-      std::ostringstream oss;
-      oss << count << " slow metadata IOs are blocked > " << complaint_time
+      CachedStackStringStream css;
+      *css << count << " slow metadata IOs are blocked > " << complaint_time
          << " secs, oldest blocked for " << (int64_t)oldest_secs << " secs";
 
-      MDSHealthMetric m(MDS_HEALTH_SLOW_METADATA_IO, HEALTH_WARN, oss.str());
+      MDSHealthMetric m(MDS_HEALTH_SLOW_METADATA_IO, HEALTH_WARN, css->strv());
       health.metrics.push_back(m);
     }
   }
 
   // Report if we have significantly exceeded our cache size limit
   if (mds->mdcache->cache_overfull()) {
-    std::ostringstream oss;
-    oss << "MDS cache is too large (" << bytes2str(mds->mdcache->cache_size())
+    CachedStackStringStream css;
+    *css << "MDS cache is too large (" << bytes2str(mds->mdcache->cache_size())
         << "/" << bytes2str(mds->mdcache->cache_limit_memory()) << "); "
         << mds->mdcache->num_inodes_with_caps << " inodes in use by clients, "
         << mds->mdcache->get_num_strays() << " stray files";
 
-    MDSHealthMetric m(MDS_HEALTH_CACHE_OVERSIZED, HEALTH_WARN, oss.str());
+    MDSHealthMetric m(MDS_HEALTH_CACHE_OVERSIZED, HEALTH_WARN, css->strv());
     health.metrics.push_back(m);
   }
 }
 
       }
     }
   } else {
-    std::ostringstream oss;
-    oss << "Invalid tag char '" << type << "' pos " << pos;
-    throw buffer::malformed_input(oss.str());
+    CachedStackStringStream css;
+    *css << "Invalid tag char '" << type << "' pos " << pos;
+    throw buffer::malformed_input(css->str());
   }
 
   return dn;
 
 using std::list;
 using std::pair;
 using std::ostream;
-using std::ostringstream;
 using std::string;
-using std::stringstream;
 
 using ceph::bufferlist;
 using ceph::Formatter;
   }
 
   if (standby_count_wanted) {
-    std::ostringstream oss;
-    oss << "insufficient standby daemons available: have " << standby_daemons.size() << "; want " << standby_count_wanted << " more";
-    summary.push_back(make_pair(HEALTH_WARN, oss.str()));
+    CachedStackStringStream css;
+    *css << "insufficient standby daemons available: have " << standby_daemons.size() << "; want " << standby_count_wanted << " more";
+    summary.push_back(make_pair(HEALTH_WARN, css->str()));
   }
 }
 
       health_check_t& fscheck = checks->get_or_add(
         "FS_WITH_FAILED_MDS", HEALTH_WARN,
         "%num% filesystem%plurals% %hasorhave% a failed mds daemon", 1);
-      ostringstream ss;
-      ss << "fs " << fs->mds_map.fs_name << " has " << stuck_failed.size()
+      CachedStackStringStream css;
+      *css << "fs " << fs->mds_map.fs_name << " has " << stuck_failed.size()
          << " failed mds" << (stuck_failed.size() > 1 ? "s" : "");
-      fscheck.detail.push_back(ss.str()); }
+      fscheck.detail.push_back(css->str()); }
 
     checks->merge(fschecks);
     standby_count_wanted = std::max(
 
   // MDS_INSUFFICIENT_STANDBY
   if (standby_count_wanted) {
-    std::ostringstream oss, dss;
-    oss << "insufficient standby MDS daemons available";
-    auto& d = checks->get_or_add("MDS_INSUFFICIENT_STANDBY", HEALTH_WARN, oss.str(), 1);
-    dss << "have " << standby_daemons.size() << "; want " << standby_count_wanted
-       << " more";
-    d.detail.push_back(dss.str());
+    CachedStackStringStream css1, css2;
+    *css1 << "insufficient standby MDS daemons available";
+    auto& d = checks->get_or_add("MDS_INSUFFICIENT_STANDBY", HEALTH_WARN, css1->str(), 1);
+    *css2 << "have " << standby_daemons.size() << "; want " << standby_count_wanted
+         << " more";
+    d.detail.push_back(css2->str());
   }
 }
 
 
     return;
 
   if (cap->revoking() & CEPH_CAP_ANY_WR) {
-    std::stringstream ss;
-    mds->evict_client(client.v, false, g_conf()->mds_session_blocklist_on_timeout, ss, nullptr);
+    CachedStackStringStream css;
+    mds->evict_client(client.v, false, g_conf()->mds_session_blocklist_on_timeout, *css, nullptr);
     return;
   }
 
       if (session->get_num_completed_flushes() >=
          (g_conf()->mds_max_completed_flushes << session->get_num_trim_flushes_warnings())) {
        session->inc_num_trim_flushes_warnings();
-       stringstream ss;
-       ss << "client." << session->get_client() << " does not advance its oldest_flush_tid ("
-          << m->get_oldest_flush_tid() << "), "
-          << session->get_num_completed_flushes()
-          << " completed flushes recorded in session";
-       mds->clog->warn() << ss.str();
-       dout(20) << __func__ << " " << ss.str() << dendl;
+       CachedStackStringStream css;
+       *css << "client." << session->get_client() << " does not advance its oldest_flush_tid ("
+            << m->get_oldest_flush_tid() << "), "
+            << session->get_num_completed_flushes()
+            << " completed flushes recorded in session";
+       mds->clog->warn() << css->strv();
+       dout(20) << __func__ << " " << css->strv() << dendl;
       }
     }
   }
     // exponential backoff of warning intervals
     if (age > mds->mdsmap->get_session_timeout() * (1 << cap->get_num_revoke_warnings())) {
       cap->inc_num_revoke_warnings();
-      stringstream ss;
-      ss << "client." << cap->get_client() << " isn't responding to mclientcaps(revoke), ino "
-        << cap->get_inode()->ino() << " pending " << ccap_string(cap->pending())
-        << " issued " << ccap_string(cap->issued()) << ", sent " << age << " seconds ago";
-      mds->clog->warn() << ss.str();
-      dout(20) << __func__ << " " << ss.str() << dendl;
+      CachedStackStringStream css;
+      *css << "client." << cap->get_client() << " isn't responding to mclientcaps(revoke), ino "
+          << cap->get_inode()->ino() << " pending " << ccap_string(cap->pending())
+          << " issued " << ccap_string(cap->issued()) << ", sent " << age << " seconds ago";
+      mds->clog->warn() << css->strv();
+      dout(20) << __func__ << " " << css->strv() << dendl;
     } else {
       dout(20) << __func__ << " silencing log message (backoff) for " << "client." << cap->get_client() << "." << cap->get_inode()->ino() << dendl;
     }
 
   f->open_object_section("mds_load");
   {
 
-    auto dump_mds_load = [f](mds_load_t& load) {
+    auto dump_mds_load = [f](const mds_load_t& load) {
       f->dump_float("request_rate", load.req_rate);
       f->dump_float("cache_hit_rate", load.cache_hit_rate);
       f->dump_float("queue_length", load.queue_len);
       f->close_section();
     };
 
-    for (auto p : mds_load) {
-      stringstream name;
-      name << "mds." << p.first;
-      f->open_object_section(name.str().c_str());
-      dump_mds_load(p.second);
+    for (const auto& [rank, load] : mds_load) {
+      CachedStackStringStream css;
+      *css << "mds." << rank;
+      f->open_object_section(css->strv());
+      dump_mds_load(load);
       f->close_section();
     }
   }
   f->close_section(); // mds_load
 
   f->open_object_section("mds_meta_load");
-  for (auto p : mds_meta_load) {
-    stringstream name;
-    name << "mds." << p.first;
-    f->dump_float(name.str().c_str(), p.second);
+  for (auto& [rank, mload] : mds_meta_load) {
+    CachedStackStringStream css;
+    *css << "mds." << rank;
+    f->dump_float(css->strv(), mload);
   }
   f->close_section(); // mds_meta_load
 
   f->open_object_section("mds_import_map");
-  for (auto p : mds_import_map) {
-    stringstream name1;
-    name1 << "mds." << p.first;
-    f->open_array_section(name1.str().c_str());
-    for (auto q : p.second) {
+  for (auto& [rank, imports] : mds_import_map) {
+    {
+      CachedStackStringStream css;
+      *css << "mds." << rank;
+      f->open_array_section(css->strv());
+    }
+    for (auto& [rank_from, mload] : imports) {
       f->open_object_section("from");
-      stringstream name2;
-      name2 << "mds." << q.first;
-      f->dump_float(name2.str().c_str(), q.second);
+      CachedStackStringStream css;
+      *css << "mds." << rank_from;
+      f->dump_float(css->strv(), mload);
       f->close_section();
     }
     f->close_section(); // mds.? array
 
   for (int i = 0; i < NUM_STRAY; ++i) {
     CInode *stray = create_system_inode(MDS_INO_STRAY(mds->get_nodeid(), i), S_IFDIR);
     CDir *straydir = stray->get_or_open_dirfrag(this, frag_t());
-    stringstream name;
-    name << "stray" << i;
-    CDentry *sdn = mydir->add_primary_dentry(name.str(), stray);
+    CachedStackStringStream css;
+    *css << "stray" << i;
+    CDentry *sdn = mydir->add_primary_dentry(css->str(), stray);
     sdn->_mark_dirty(mds->mdlog->get_current_segment());
 
     stray->_get_inode()->dirstat = straydir->get_fnode()->fragstat;
   // open or create stray
   uint64_t num_strays = 0;
   for (int i = 0; i < NUM_STRAY; ++i) {
-    stringstream name;
-    name << "stray" << i;
-    CDentry *straydn = mydir->lookup(name.str());
+    CachedStackStringStream css;
+    *css << "stray" << i;
+    CDentry *straydn = mydir->lookup(css->str());
 
     // allow for older fs's with stray instead of stray0
     if (straydn == NULL && i == 0)
       straydn = mydir->lookup("stray");
 
     if (!straydn || !straydn->get_linkage()->get_inode()) {
-      _create_system_file(mydir, name.str().c_str(), create_system_inode(MDS_INO_STRAY(mds->get_nodeid(), i), S_IFDIR),
+      _create_system_file(mydir, css->strv(), create_system_inode(MDS_INO_STRAY(mds->get_nodeid(), i), S_IFDIR),
                          new C_MDS_RetryOpenRoot(this));
       return;
     }
 {
   dout(10) << "export_remaining_imported_caps" << dendl;
 
-  stringstream warn_str;
+  CachedStackStringStream css;
 
   int count = 0;
   for (auto p = cap_imports.begin(); p != cap_imports.end(); ++p) {
-    warn_str << " ino " << p->first << "\n";
+    *css << " ino " << p->first << "\n";
     for (auto q = p->second.begin(); q != p->second.end(); ++q) {
       Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(q->first.v));
       if (session) {
   cap_imports.clear();
   cap_reconnect_waiters.clear();
 
-  if (warn_str.peek() != EOF) {
-    mds->clog->warn() << "failed to reconnect caps for missing inodes:";
-    mds->clog->warn(warn_str);
+  if (css->strv().length()) {
+    mds->clog->warn() << "failed to reconnect caps for missing inodes:"
+                      << css->strv();
   }
 }
 
   if (!reconnected_snaprealms.empty()) {
     dout(5) << "open_snaprealms has unconnected snaprealm:" << dendl;
     for (auto& p : reconnected_snaprealms) {
-      stringstream warn_str;
-      warn_str << " " << p.first << " {";
+      CachedStackStringStream css;
+      *css << " " << p.first << " {";
       bool first = true;
       for (auto& q : p.second) {
         if (!first)
-          warn_str << ", ";
-        warn_str << "client." << q.first << "/" << q.second;
+          *css << ", ";
+        *css << "client." << q.first << "/" << q.second;
       }
-      warn_str << "}";
-      dout(5) << warn_str.str() << dendl;
+      *css << "}";
+      dout(5) << css->strv() << dendl;
     }
   }
   ceph_assert(rejoin_waiters.empty());
 
   if (threshold && cache_size() > threshold) {
     if (f) {
-      std::stringstream ss;
-      ss << "cache usage exceeds dump threshold";
+      CachedStackStringStream css;
+      *css << "cache usage exceeds dump threshold";
       f->open_object_section("result");
-      f->dump_string("error", ss.str());
+      f->dump_string("error", css->strv());
       f->close_section();
     } else {
       derr << "cache usage exceeds dump threshold" << dendl;
       f->close_section();
       return 1;
     } 
-    ostringstream ss;
-    ss << *in << std::endl;
-    std::string s = ss.str();
-    r = safe_write(fd, s.c_str(), s.length());
+    CachedStackStringStream css;
+    *css << *in << std::endl;
+    auto sv = css->strv();
+    r = safe_write(fd, sv.data(), sv.size());
     if (r < 0)
       return r;
     auto&& dfs = in->get_dirfrags();
     for (auto &dir : dfs) {
-      ostringstream tt;
-      tt << " " << *dir << std::endl;
-      std::string t = tt.str();
-      r = safe_write(fd, t.c_str(), t.length());
+      CachedStackStringStream css2;
+      *css2 << " " << *dir << std::endl;
+      auto sv = css2->strv();
+      r = safe_write(fd, sv.data(), sv.size());
       if (r < 0)
         return r;
       for (auto &p : dir->items) {
        CDentry *dn = p.second;
-        ostringstream uu;
-        uu << "  " << *dn << std::endl;
-        std::string u = uu.str();
-        r = safe_write(fd, u.c_str(), u.length());
+        CachedStackStringStream css3;
+        *css3 << "  " << *dn << std::endl;
+        auto sv = css3->strv();
+        r = safe_write(fd, sv.data(), sv.size());
         if (r < 0)
           return r;
       }
 
   {
     f->open_object_section("replicas");
     for (const auto &it : get_replicas()) {
-      std::ostringstream rank_str;
-      rank_str << it.first;
-      f->dump_int(rank_str.str().c_str(), it.second);
+      CachedStackStringStream css;
+      *css << it.first;
+      f->dump_int(css->strv(), it.second);
     }
     f->close_section();
   }
 #ifdef MDS_REF_SET
     f->open_object_section("pins");
     for(const auto& p : ref_map) {
-      f->dump_int(pin_name(p.first).data(), p.second);
+      f->dump_int(pin_name(p.first), p.second);
     }
     f->close_section();
 #endif
 
 
   int r = -ENOSYS;
   bufferlist outbl;
-  stringstream ss;
+  CachedStackStringStream css;
+  auto& ss = *css;
   if (command == "status") {
     dump_status(f);
     r = 0;
 
   int r = 0;
   cmdmap_t cmdmap;
-  std::stringstream ss;
-  std::string outs;
+  CachedStackStringStream css;
+  auto& ss = *css;
   bufferlist outbl;
 
   // If someone is using a closed session for sending commands (e.g.
   } else if (m->cmd.empty()) {
     r = -EINVAL;
     ss << "no command given";
-    outs = ss.str();
   } else if (!TOPNSPC::common::cmdmap_from_json(m->cmd, &cmdmap, ss)) {
     r = -EINVAL;
-    outs = ss.str();
   } else {
     cct->get_admin_socket()->queue_tell_command(m);
     return;
   }
 
-  auto reply = make_message<MCommandReply>(r, outs);
+  auto reply = make_message<MCommandReply>(r, ss.str());
   reply->set_tid(m->get_tid());
   reply->set_data(outbl);
   m->get_connection()->send_message2(reply);
 
 using std::pair;
 using std::string;
 using std::set;
-using std::stringstream;
 
 using ceph::bufferlist;
 using ceph::Formatter;
                        list<pair<health_status_t,string> > *detail) const
 {
   if (!failed.empty()) {
-    std::ostringstream oss;
-    oss << "mds rank"
+    CachedStackStringStream css;
+    *css << "mds rank"
        << ((failed.size() > 1) ? "s ":" ")
        << failed
        << ((failed.size() > 1) ? " have":" has")
        << " failed";
-    summary.push_back(make_pair(HEALTH_ERR, oss.str()));
+    summary.push_back(make_pair(HEALTH_ERR, css->str()));
     if (detail) {
-      for (set<mds_rank_t>::const_iterator p = failed.begin(); p != failed.end(); ++p) {
-       std::ostringstream oss;
-       oss << "mds." << *p << " has failed";
-       detail->push_back(make_pair(HEALTH_ERR, oss.str()));
+      for (const auto& r : failed) {
+        CachedStackStringStream css;
+       *css << "mds." << r << " has failed";
+       detail->push_back(make_pair(HEALTH_ERR, css->str()));
       }
     }
   }
 
   if (!damaged.empty()) {
-    std::ostringstream oss;
-    oss << "mds rank"
-       << ((damaged.size() > 1) ? "s ":" ")
-       << damaged
-       << ((damaged.size() > 1) ? " are":" is")
-       << " damaged";
-    summary.push_back(make_pair(HEALTH_ERR, oss.str()));
+    CachedStackStringStream css;
+    *css << "mds rank"
+        << ((damaged.size() > 1) ? "s ":" ")
+        << damaged
+        << ((damaged.size() > 1) ? " are":" is")
+        << " damaged";
+    summary.push_back(make_pair(HEALTH_ERR, css->str()));
     if (detail) {
-      for (set<mds_rank_t>::const_iterator p = damaged.begin(); p != damaged.end(); ++p) {
-       std::ostringstream oss;
-       oss << "mds." << *p << " is damaged";
-       detail->push_back(make_pair(HEALTH_ERR, oss.str()));
+      for (const auto& r : damaged) {
+        CachedStackStringStream css;
+       *css << "mds." << r << " is damaged";
+       detail->push_back(make_pair(HEALTH_ERR, css->str()));
       }
     }
   }
          continue;
        mds_gid_t gid = up.find(i)->second;
        const auto& info = mds_info.at(gid);
-       stringstream ss;
+        CachedStackStringStream css;
        if (is_resolve(i))
-         ss << "mds." << info.name << " at " << info.addrs
+         *css << "mds." << info.name << " at " << info.addrs
             << " rank " << i << " is resolving";
        if (is_replay(i))
-         ss << "mds." << info.name << " at " << info.addrs
+         *css << "mds." << info.name << " at " << info.addrs
             << " rank " << i << " is replaying journal";
        if (is_rejoin(i))
-         ss << "mds." << info.name << " at " << info.addrs
+         *css << "mds." << info.name << " at " << info.addrs
             << " rank " << i << " is rejoining";
        if (is_reconnect(i))
-         ss << "mds." << info.name << " at " << info.addrs
+         *css << "mds." << info.name << " at " << info.addrs
             << " rank " << i << " is reconnecting to clients";
-       if (ss.str().length())
-         detail->push_back(make_pair(HEALTH_WARN, ss.str()));
+       if (css->strv().length())
+         detail->push_back(make_pair(HEALTH_WARN, css->str()));
       }
     }
   }
 
   {
-  stringstream ss;
-  ss << fs_name << " max_mds " << max_mds;
-  summary.push_back(make_pair(HEALTH_WARN, ss.str()));
+    CachedStackStringStream css;
+    *css << fs_name << " max_mds " << max_mds;
+    summary.push_back(make_pair(HEALTH_WARN, css->str()));
   }
 
   if ((mds_rank_t)up.size() < max_mds) {
-    stringstream ss;
-    ss << fs_name << " has " << up.size()
-       << " active MDS(s), but has max_mds of " << max_mds;
-    summary.push_back(make_pair(HEALTH_WARN, ss.str()));
+    CachedStackStringStream css;
+    *css << fs_name << " has " << up.size()
+         << " active MDS(s), but has max_mds of " << max_mds;
+    summary.push_back(make_pair(HEALTH_WARN, css->str()));
   }
 
   set<string> laggy;
     if (info.laggy()) {
       laggy.insert(info.name);
       if (detail) {
-       std::ostringstream oss;
-       oss << "mds." << info.name << " at " << info.addrs
+        CachedStackStringStream css;
+       *css << "mds." << info.name << " at " << info.addrs
            << " is laggy/unresponsive";
-       detail->push_back(make_pair(HEALTH_WARN, oss.str()));
+       detail->push_back(make_pair(HEALTH_WARN, css->str()));
       }
     }
   }
 
   if (!laggy.empty()) {
-    std::ostringstream oss;
-    oss << "mds " << laggy
-       << ((laggy.size() > 1) ? " are":" is")
-       << " laggy";
-    summary.push_back(make_pair(HEALTH_WARN, oss.str()));
+    CachedStackStringStream css;
+    *css << "mds " << laggy
+        << ((laggy.size() > 1) ? " are":" is")
+        << " laggy";
+    summary.push_back(make_pair(HEALTH_WARN, css->str()));
   }
 
   if (get_max_mds() > 1 &&
       was_snaps_ever_allowed() && !allows_multimds_snaps()) {
-    std::ostringstream oss;
-    oss << "multi-active mds while there are snapshots possibly created by pre-mimic MDS";
-    summary.push_back(make_pair(HEALTH_WARN, oss.str()));
+    CachedStackStringStream css;
+    *css << "multi-active mds while there are snapshots possibly created by pre-mimic MDS";
+    summary.push_back(make_pair(HEALTH_WARN, css->str()));
   }
 }
 
     health_check_t& check = checks->get_or_add("MDS_DAMAGE", HEALTH_ERR,
                                               "%num% mds daemon%plurals% damaged",
                                               damaged.size());
-    for (auto p : damaged) {
-      std::ostringstream oss;
-      oss << "fs " << fs_name << " mds." << p << " is damaged";
-      check.detail.push_back(oss.str());
+    for (const auto& p : damaged) {
+      CachedStackStringStream css;
+      *css << "fs " << fs_name << " mds." << p << " is damaged";
+      check.detail.push_back(css->str());
     }
   }
 
     health_check_t& fscheck = checks->get_or_add(
       "FS_DEGRADED", HEALTH_WARN,
       "%num% filesystem%plurals% %isorare% degraded", 1);
-    std::ostringstream ss;
-    ss << "fs " << fs_name << " is degraded";
-    fscheck.detail.push_back(ss.str());
+    CachedStackStringStream css;
+    *css << "fs " << fs_name << " is degraded";
+    fscheck.detail.push_back(css->str());
 
     list<string> detail;
     for (mds_rank_t i = mds_rank_t(0); i< get_max_mds(); i++) {
        continue;
       mds_gid_t gid = up.find(i)->second;
       const auto& info = mds_info.at(gid);
-      stringstream ss;
-      ss << "fs " << fs_name << " mds." << info.name << " at "
+      CachedStackStringStream css;
+      *css << "fs " << fs_name << " mds." << info.name << " at "
         << info.addrs << " rank " << i;
       if (is_resolve(i))
-       ss << " is resolving";
+       *css << " is resolving";
       if (is_replay(i))
-       ss << " is replaying journal";
+       *css << " is replaying journal";
       if (is_rejoin(i))
-       ss << " is rejoining";
+       *css << " is rejoining";
       if (is_reconnect(i))
-       ss << " is reconnecting to clients";
-      if (ss.str().length())
-       detail.push_back(ss.str());
+       *css << " is reconnecting to clients";
+      if (css->strv().length())
+       detail.push_back(css->str());
     }
   }
 
     health_check_t& check = checks->add(
       "MDS_UP_LESS_THAN_MAX", HEALTH_WARN,
       "%num% filesystem%plurals% %isorare% online with fewer MDS than max_mds", 1);
-    stringstream ss;
-    ss << "fs " << fs_name << " has " << get_num_in_mds()
-       << " MDS online, but wants " << get_max_mds();
-    check.detail.push_back(ss.str());
+    CachedStackStringStream css;
+    *css << "fs " << fs_name << " has " << get_num_in_mds()
+         << " MDS online, but wants " << get_max_mds();
+    check.detail.push_back(css->str());
   }
 
   // MDS_ALL_DOWN
     health_check_t &check = checks->add(
       "MDS_ALL_DOWN", HEALTH_ERR,
       "%num% filesystem%plurals% %isorare% offline", 1);
-    stringstream ss;
-    ss << "fs " << fs_name << " is offline because no MDS is active for it.";
-    check.detail.push_back(ss.str());
+    CachedStackStringStream css;
+    *css << "fs " << fs_name << " is offline because no MDS is active for it.";
+    check.detail.push_back(css->str());
   }
 
   if (get_max_mds() > 1 &&
     health_check_t &check = checks->add(
       "MULTIMDS_WITH_OLDSNAPS", HEALTH_ERR,
       "%num% filesystem%plurals% %isorare% multi-active mds with old snapshots", 1);
-    stringstream ss;
-    ss << "multi-active mds while there are snapshots possibly created by pre-mimic MDS";
-    check.detail.push_back(ss.str());
+    CachedStackStringStream css;
+    *css << "multi-active mds while there are snapshots possibly created by pre-mimic MDS";
+    check.detail.push_back(css->str());
   }
 
   if (get_inline_data_enabled()) {
     health_check_t &check = checks->add(
       "FS_INLINE_DATA_DEPRECATED", HEALTH_WARN,
       "%num% filesystem%plurals% with deprecated feature inline_data", 1);
-    stringstream ss;
-    ss << "fs " << fs_name << " has deprecated feature inline_data enabled.";
-    check.detail.push_back(ss.str());
+    CachedStackStringStream css;
+    *css << "fs " << fs_name << " has deprecated feature inline_data enabled.";
+    check.detail.push_back(css->str());
   }
 }
 
 std::string MDSMap::mds_info_t::human_name() const
 {
   // Like "daemon mds.myhost restarted", "Activating daemon mds.myhost"
-  std::ostringstream out;
-  out << "daemon mds." << name;
-  return out.str();
+  CachedStackStringStream css;
+  *css << "daemon mds." << name;
+  return css->str();
 }
 
 void MDSMap::encode(bufferlist& bl, uint64_t features) const
 
   if (already_sent)
     return;
 
-  stringstream ss;
-  ss << "{\"prefix\":\"fs set\", \"fs_name\":\"" <<  mdsmap->get_fs_name() << "\", ";
-  ss << "\"var\":\"allow_multimds_snaps\", \"val\":\"true\", ";
-  ss << "\"confirm\":\"--yes-i-am-really-a-mds\"}";
-  std::vector<std::string> cmd = {ss.str()};
+  CachedStackStringStream css;
+  *css << "{\"prefix\":\"fs set\", \"fs_name\":\"" <<  mdsmap->get_fs_name() << "\", ";
+  *css << "\"var\":\"allow_multimds_snaps\", \"val\":\"true\", ";
+  *css << "\"confirm\":\"--yes-i-am-really-a-mds\"}";
+  std::vector<std::string> cmd = {css->str()};
 
   dout(0) << __func__ << ": sending mon command: " << cmd[0] << dendl;
 
 
     C_GatherBuilder gather(g_ceph_context, new C_MDSInternalNoop);
     for (const auto &s : victims) {
-      std::stringstream ss;
+      CachedStackStringStream css;
       evict_client(s->get_client().v, false,
-                   g_conf()->mds_session_blocklist_on_evict, ss, gather.new_sub());
+                   g_conf()->mds_session_blocklist_on_evict, *css, gather.new_sub());
     }
     gather.activate();
   }
   std::function<void(int,const std::string&,bufferlist&)> on_finish)
 {
   int r = 0;
-  stringstream ss;
+  CachedStackStringStream css;
   bufferlist outbl;
   if (command == "dump_ops_in_flight" ||
       command == "ops") {
     if (!op_tracker.dump_ops_in_flight(f)) {
-      ss << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
+      *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
     }
   } else if (command == "dump_blocked_ops") {
     if (!op_tracker.dump_ops_in_flight(f, true)) {
-      ss << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
+      *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
     }
   } else if (command == "dump_historic_ops") {
     if (!op_tracker.dump_historic_ops(f)) {
-      ss << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
+      *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
     }
   } else if (command == "dump_historic_ops_by_duration") {
     if (!op_tracker.dump_historic_ops(f, true)) {
-      ss << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
+      *css << "op_tracker disabled; set mds_enable_op_tracker=true to enable";
     }
   } else if (command == "osdmap barrier") {
     int64_t target_epoch = 0;
     bool got_val = cmd_getval(cmdmap, "target_epoch", target_epoch);
 
     if (!got_val) {
-      ss << "no target epoch given";
+      *css << "no target epoch given";
       r = -EINVAL;
       goto out;
     }
     cmd_getval(cmdmap, "filters", filter_args);
 
     SessionFilter filter;
-    r = filter.parse(filter_args, &ss);
+    r = filter.parse(filter_args, css.get());
     if (r != 0) {
       goto out;
     }
     cmd_getval(cmdmap, "filters", filter_args);
 
     SessionFilter filter;
-    r = filter.parse(filter_args, &ss);
+    r = filter.parse(filter_args, css.get());
     if (r != 0) {
       r = -EINVAL;
       goto out;
   } else if (command == "session kill") {
     std::string client_id;
     if (!cmd_getval(cmdmap, "client_id", client_id)) {
-      ss << "Invalid client_id specified";
+      *css << "Invalid client_id specified";
       r = -ENOENT;
       goto out;
     }
     std::lock_guard l(mds_lock);
     bool evicted = evict_client(strtol(client_id.c_str(), 0, 10), true,
-        g_conf()->mds_session_blocklist_on_evict, ss);
+        g_conf()->mds_session_blocklist_on_evict, *css);
     if (!evicted) {
-      dout(15) << ss.str() << dendl;
+      dout(15) << css->strv() << dendl;
       r = -ENOENT;
     }
   } else if (command == "session config" ||
     bool got_value = cmd_getval(cmdmap, "value", value);
 
     std::lock_guard l(mds_lock);
-    r = config_client(client_id, !got_value, option, value, ss);
+    r = config_client(client_id, !got_value, option, value, *css);
   } else if (command == "scrub start" ||
             command == "scrub_start") {
     string path;
 
     /* Multiple MDS scrub is not currently supported. See also: https://tracker.ceph.com/issues/12274 */
     if (mdsmap->get_max_mds() > 1) {
-      ss << "Scrub is not currently supported for multiple active MDS. Please reduce max_mds to 1 and then scrub.";
+      *css << "Scrub is not currently supported for multiple active MDS. Please reduce max_mds to 1 and then scrub.";
       r = -EINVAL;
       goto out;
     }
   } else if (command == "export dir") {
     string path;
     if(!cmd_getval(cmdmap, "path", path)) {
-      ss << "malformed path";
+      *css << "malformed path";
       r = -EINVAL;
       goto out;
     }
     int64_t rank;
     if(!cmd_getval(cmdmap, "rank", rank)) {
-      ss << "malformed rank";
+      *css << "malformed rank";
       r = -EINVAL;
       goto out;
     }
     std::lock_guard l(mds_lock);
     mdcache->cache_status(f);
   } else if (command == "dump tree") {
-    command_dump_tree(cmdmap, ss, f);
+    command_dump_tree(cmdmap, *css, f);
   } else if (command == "dump loads") {
     std::lock_guard l(mds_lock);
     r = balancer->dump_loads(f);
        snapserver->dump(f);
       } else {
        r = -EXDEV;
-       ss << "Not snapserver";
+       *css << "Not snapserver";
       }
     } else {
       r = snapclient->dump_cache(f);
     std::lock_guard l(mds_lock);
     mdcache->force_readonly();
   } else if (command == "dirfrag split") {
-    command_dirfrag_split(cmdmap, ss);
+    command_dirfrag_split(cmdmap, *css);
   } else if (command == "dirfrag merge") {
-    command_dirfrag_merge(cmdmap, ss);
+    command_dirfrag_merge(cmdmap, *css);
   } else if (command == "dirfrag ls") {
-    command_dirfrag_ls(cmdmap, ss, f);
+    command_dirfrag_ls(cmdmap, *css, f);
   } else if (command == "openfiles ls") {
     command_openfiles_ls(f);
   } else if (command == "dump inode") {
-    command_dump_inode(f, cmdmap, ss);
+    command_dump_inode(f, cmdmap, *css);
   } else if (command == "damage ls") {
     std::lock_guard l(mds_lock);
     damage_table.dump(f);
     r = -ENOSYS;
   }
 out:
-  on_finish(r, ss.str(), outbl);
+  on_finish(r, css->str(), outbl);
 }
 
 /**
                                             on_finish(r, {}, bl);
                                           }));
   for (const auto s : victims) {
-    std::stringstream ss;
+    CachedStackStringStream css;
     evict_client(s->get_client().v, false,
-                 g_conf()->mds_session_blocklist_on_evict, ss, gather.new_sub());
+                 g_conf()->mds_session_blocklist_on_evict, *css, gather.new_sub());
   }
   gather.activate();
 }
   ceph_assert(f != NULL);
 
   C_SaferCond cond;
-  std::stringstream ss;
+  CachedStackStringStream css;
   {
     std::lock_guard locker(mds_lock);
-    C_Flush_Journal *flush_journal = new C_Flush_Journal(mdcache, mdlog, this, &ss, &cond);
+    C_Flush_Journal *flush_journal = new C_Flush_Journal(mdcache, mdlog, this, css.get(), &cond);
     flush_journal->send();
   }
   int r = cond.wait();
 
   f->open_object_section("result");
-  f->dump_string("message", ss.str());
+  f->dump_string("message", css->strv());
   f->dump_int("return_code", r);
   f->close_section();
 }
   }
 
   dout(4) << "Preparing blocklist command... (wait=" << wait << ")" << dendl;
-  stringstream ss;
-  ss << "{\"prefix\":\"osd blocklist\", \"blocklistop\":\"add\",";
-  ss << "\"addr\":\"";
-  ss << addr;
-  ss << "\"}";
-  std::string tmp = ss.str();
-  std::vector<std::string> cmd = {tmp};
+  CachedStackStringStream css;
+  *css << "{\"prefix\":\"osd blocklist\", \"blocklistop\":\"add\",";
+  *css << "\"addr\":\"";
+  *css << addr;
+  *css << "\"}";
+  std::vector<std::string> cmd = {css->str()};
 
   auto kill_client_session = [this, session_id, wait, on_killed](){
     ceph_assert(ceph_mutex_is_locked_by_me(mds_lock));
 
       } else {
        decode(magic, p);
        if (magic != CEPH_FS_ONDISK_MAGIC) {
-         std::ostringstream oss;
-         oss << "invalid magic '" << magic << "'";
-         throw buffer::malformed_input(oss.str());
+         CachedStackStringStream css;
+         *css << "invalid magic '" << magic << "'";
+         throw buffer::malformed_input(css->str());
        }
 
        DECODE_START(1, p);
       }
 
       if (num_objs > MAX_OBJECTS) {
-         std::ostringstream oss;
-         oss << "invalid object count '" << num_objs << "'";
-         throw buffer::malformed_input(oss.str());
+         CachedStackStringStream css;
+         *css << "invalid object count '" << num_objs << "'";
+         throw buffer::malformed_input(css->str());
       }
       if (jstate > JOURNAL_FINISH) {
-         std::ostringstream oss;
-         oss << "invalid journal state '" << jstate << "'";
-         throw buffer::malformed_input(oss.str());
+         CachedStackStringStream css;
+         *css << "invalid journal state '" << jstate << "'";
+         throw buffer::malformed_input(css->str());
       }
 
       if (version > omap_version) {
 
     // Put the verbose JSON output into the MDS log for later inspection
     JSONFormatter f;
     result.dump(&f);
-    std::ostringstream out;
-    f.flush(out);
-    derr << __func__ << " scrub error on inode " << *in << ": " << out.str()
+    CachedStackStringStream css;
+    f.flush(*css);
+    derr << __func__ << " scrub error on inode " << *in << ": " << css->strv()
          << dendl;
   } else {
     dout(10) << __func__ << " scrub passed on inode " << *in << dendl;
 
   f->open_object_section("result");
 
-  std::stringstream ss;
+  CachedStackStringStream css;
   bool have_more = false;
 
   if (state == STATE_IDLE) {
-    ss << "no active scrubs running";
+    *css << "no active scrubs running";
   } else if (state == STATE_RUNNING) {
     if (clear_inode_stack) {
-      ss << "ABORTING";
+      *css << "ABORTING";
     } else {
-      ss << "scrub active";
+      *css << "scrub active";
     }
-    ss << " (" << stack_size << " inodes in the stack)";
+    *css << " (" << stack_size << " inodes in the stack)";
   } else {
     if (state == STATE_PAUSING || state == STATE_PAUSED) {
       have_more = true;
-      ss << state;
+      *css << state;
     }
     if (clear_inode_stack) {
       if (have_more) {
-        ss << "+";
+        *css << "+";
       }
-      ss << "ABORTING";
+      *css << "ABORTING";
     }
 
-    ss << " (" << stack_size << " inodes in the stack)";
+    *css << " (" << stack_size << " inodes in the stack)";
   }
-  f->dump_string("status", ss.str());
+  f->dump_string("status", css->strv());
 
   f->open_object_section("scrubs");
   for (auto &inode : scrub_origins) {
 
     f->dump_string("path", scrub_inode_path(inode));
 
-    std::stringstream optss;
+    CachedStackStringStream optcss;
     if (header->get_recursive()) {
-      optss << "recursive";
+      *optcss << "recursive";
       have_more = true;
     }
     if (header->get_repair()) {
       if (have_more) {
-        optss << ",";
+        *optcss << ",";
       }
-      optss << "repair";
+      *optcss << "repair";
       have_more = true;
     }
     if (header->get_force()) {
       if (have_more) {
-        optss << ",";
+        *optcss << ",";
       }
-      optss << "force";
+      *optcss << "force";
     }
 
-    f->dump_string("options", optss.str());
+    f->dump_string("options", optcss->strv());
     f->close_section(); // scrub id
   }
   f->close_section(); // scrubs
 
     if (blocklisted || !g_conf()->mds_session_blocklist_on_evict) {
       kill_session(target, send_reply);
     } else {
-      std::stringstream ss;
-      mds->evict_client(target->get_client().v, false, true, ss, send_reply);
+      CachedStackStringStream css;
+      mds->evict_client(target->get_client().v, false, true, *css, send_reply);
     }
   } else if (reply) {
     mds->send_message_client(reply, session);
       feature_bitset_t missing_features = required_client_features;
       missing_features -= client_metadata.features;
       if (!missing_features.empty()) {
-       stringstream ss;
-       ss << "missing required features '" << missing_features << "'";
-       send_reject_message(ss.str());
+       CachedStackStringStream css;
+       *css << "missing required features '" << missing_features << "'";
+       send_reject_message(css->strv());
        mds->clog->warn() << "client session (" << session->info.inst
                           << ") lacks required features " << missing_features
                           << "; client supports " << client_metadata.features;
       // root is actually within the caps of the session
       if (auto it = client_metadata.find("root"); it != client_metadata.end()) {
        auto claimed_root = it->second;
-       stringstream ss;
+       CachedStackStringStream css;
        bool denied = false;
        // claimed_root has a leading "/" which we strip before passing
        // into caps check
        if (claimed_root.empty() || claimed_root[0] != '/') {
          denied = true;
-         ss << "invalue root '" << claimed_root << "'";
+         *css << "invalue root '" << claimed_root << "'";
        } else if (!session->auth_caps.path_capable(claimed_root.substr(1))) {
          denied = true;
-         ss << "non-allowable root '" << claimed_root << "'";
+         *css << "non-allowable root '" << claimed_root << "'";
        }
 
        if (denied) {
          // Tell the client we're rejecting their open
-         send_reject_message(ss.str());
-         mds->clog->warn() << "client session with " << ss.str()
+         send_reject_message(css->strv());
+         mds->clog->warn() << "client session with " << css->strv()
                            << " denied (" << session->info.inst << ")";
          session->clear();
          break;
             << " last renewed caps " << last_cap_renew_span << "s ago" << dendl;
 
     if (g_conf()->mds_session_blocklist_on_timeout) {
-      std::stringstream ss;
-      mds->evict_client(session->get_client().v, false, true, ss, nullptr);
+      CachedStackStringStream css;
+      mds->evict_client(session->get_client().v, false, true, *css, nullptr);
     } else {
       kill_session(session, NULL);
     }
     dout(1) << __func__ << ": evicting cap revoke non-responder client id "
             << client << dendl;
 
-    std::stringstream ss;
+    CachedStackStringStream css;
     bool evicted = mds->evict_client(client.v, false,
                                      g_conf()->mds_session_blocklist_on_evict,
-                                     ss, nullptr);
+                                     *css, nullptr);
     if (evicted && logger) {
       logger->inc(l_mdss_cap_revoke_eviction);
     }
       feature_bitset_t missing_features = required_client_features;
       missing_features -= session->info.client_metadata.features;
       if (!missing_features.empty()) {
-       stringstream ss;
-       ss << "missing required features '" << missing_features << "'";
-       error_str = ss.str();
+       CachedStackStringStream css;
+       *css << "missing required features '" << missing_features << "'";
+       error_str = css->strv();
       }
     }
 
 
        mds->clog->warn() << "evicting session " << *session << ", missing required features '"
                          << missing_features << "'";
-       std::stringstream ss;
+       CachedStackStringStream css;
        mds->evict_client(session->get_client().v, false,
-                         g_conf()->mds_session_blocklist_on_evict, ss);
+                         g_conf()->mds_session_blocklist_on_evict, *css);
       }
     }
   }
                      << " seconds during MDS startup";
 
     if (g_conf()->mds_session_blocklist_on_timeout) {
-      std::stringstream ss;
-      mds->evict_client(session->get_client().v, false, true, ss,
+      CachedStackStringStream css;
+      mds->evict_client(session->get_client().v, false, true, *css,
                        gather.new_sub());
     } else {
       kill_session(session, NULL, true);
       if (session->get_num_completed_requests() >=
          (g_conf()->mds_max_completed_requests << session->get_num_trim_requests_warnings())) {
        session->inc_num_trim_requests_warnings();
-       stringstream ss;
-       ss << "client." << session->get_client() << " does not advance its oldest_client_tid ("
+       CachedStackStringStream css;
+       *css << "client." << session->get_client() << " does not advance its oldest_client_tid ("
           << req->get_oldest_client_tid() << "), "
           << session->get_num_completed_requests()
           << " completed requests recorded in session\n";
-       mds->clog->warn() << ss.str();
-       dout(20) << __func__ << " " << ss.str() << dendl;
+       mds->clog->warn() << css->strv();
+       dout(20) << __func__ << " " << css->strv() << dendl;
       }
     }
   }
 
        session->is_killing()) {
       dout(20) << "  " << name << dendl;
       // Serialize K
-      std::ostringstream k;
-      k << name;
+      CachedStackStringStream css;
+      *css << name;
 
       // Serialize V
       bufferlist bl;
       session->info.encode(bl, mds->mdsmap->get_up_features());
 
       // Add to RADOS op
-      to_set[k.str()] = bl;
+      to_set[std::string(css->strv())] = bl;
 
       session->clear_dirty_completed_requests();
     } else {
   for(std::set<entity_name_t>::const_iterator i = null_sessions.begin();
       i != null_sessions.end(); ++i) {
     dout(20) << "  " << *i << dendl;
-    std::ostringstream k;
-    k << *i;
-    to_remove.insert(k.str());
+    CachedStackStringStream css;
+    *css << *i;
+    to_remove.insert(css->str());
   }
   if (!to_remove.empty()) {
     op.omap_rm_keys(to_remove);
     session->clear_dirty_completed_requests();
 
     // Serialize K
-    std::ostringstream k;
-    k << session_id;
+    CachedStackStringStream css;
+    *css << session_id;
 
     // Serialize V
     bufferlist bl;
     session->info.encode(bl, mds->mdsmap->get_up_features());
 
     // Add to RADOS op
-    to_set[k.str()] = bl;
+    to_set[css->str()] = bl;
 
     // Complete this write transaction?
     if (i == write_sessions.size() - 1
 
 int SessionFilter::parse(
     const std::vector<std::string> &args,
-    std::stringstream *ss)
+    std::ostream *ss)
 {
   ceph_assert(ss != NULL);
 
 
   bool match(
       const Session &session,
       std::function<bool(client_t)> is_reconnecting) const;
-  int parse(const std::vector<std::string> &args, std::stringstream *ss);
+  int parse(const std::vector<std::string> &args, std::ostream *ss);
   void set_reconnecting(bool v)
   {
     reconnecting.first = true;
 
 
   f->open_object_section("need_to_purge");
   for (map<int, set<snapid_t> >::const_iterator i = need_to_purge.begin(); i != need_to_purge.end(); ++i) {
-    stringstream pool_id;
-    pool_id << i->first;
-    f->open_array_section(pool_id.str().c_str());
+    CachedStackStringStream css;
+    *css << i->first;
+    f->open_array_section(css->strv());
     for (set<snapid_t>::const_iterator s = i->second.begin(); s != i->second.end(); ++s) {
       f->dump_unsigned("snapid", s->val);
     }
 
 
 std::string cephfs_stringify_features(const feature_bitset_t& features)
 {
-  std::ostringstream ss;
+  CachedStackStringStream css;
   bool first = true;
-  ss << "{";
+  *css << "{";
   for (size_t i = 0; i < feature_names.size(); ++i) {
     if (!features.test(i))
       continue;
     if (!first)
-      ss << ",";
-    ss << i << "=" << cephfs_feature_name(i);
+      *css << ",";
+    *css << i << "=" << cephfs_feature_name(i);
     first = false;
   }
-  ss << "}";
-  return ss.str();
+  *css << "}";
+  return css->str();
 }
 
 void cephfs_dump_features(ceph::Formatter *f, const feature_bitset_t& features)
 
        !in->get_inode()->layout.is_valid()) {
       dout(0) << "EMetaBlob.replay invalid layout on ino " << *in
               << ": " << in->get_inode()->layout << dendl;
-      std::ostringstream oss;
-      oss << "Invalid layout for inode " << in->ino() << " in journal";
-      mds->clog->error() << oss.str();
+      CachedStackStringStream css;
+      *css << "Invalid layout for inode " << in->ino() << " in journal";
+      mds->clog->error() << css->strv();
       mds->damaged();
       ceph_abort();  // Should be unreachable because damaged() calls respawn()
     }
        if (!dn->get_linkage()->is_null()) {
          if (dn->get_linkage()->is_primary()) {
            unlinked[dn->get_linkage()->get_inode()] = dir;
-           stringstream ss;
-           ss << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
+           CachedStackStringStream css;
+           *css << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
               << " " << *dn->get_linkage()->get_inode() << " should be " << in->ino();
-           dout(0) << ss.str() << dendl;
-           mds->clog->warn(ss);
+           dout(0) << css->strv() << dendl;
+           mds->clog->warn() << css->strv();
          }
          dir->unlink_inode(dn, false);
        }
          if (!dn->get_linkage()->is_null()) { // note: might be remote.  as with stray reintegration.
            if (dn->get_linkage()->is_primary()) {
              unlinked[dn->get_linkage()->get_inode()] = dir;
-             stringstream ss;
-             ss << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
+             CachedStackStringStream css;
+             *css << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
                 << " " << *dn->get_linkage()->get_inode() << " should be " << in->ino();
-             dout(0) << ss.str() << dendl;
-             mds->clog->warn(ss);
+             dout(0) << css->strv() << dendl;
+             mds->clog->warn() << css->strv();
            }
            dir->unlink_inode(dn, false);
          }
          dout(10) << "EMetaBlob.replay unlinking " << *dn << dendl;
          if (dn->get_linkage()->is_primary()) {
            unlinked[dn->get_linkage()->get_inode()] = dir;
-           stringstream ss;
-           ss << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
+           CachedStackStringStream css;
+           *css << "EMetaBlob.replay FIXME had dentry linked to wrong inode " << *dn
               << " " << *dn->get_linkage()->get_inode() << " should be remote " << rb.ino;
-           dout(0) << ss.str() << dendl;
+           dout(0) << css->strv() << dendl;
          }
          dir->unlink_inode(dn, false);
        }
 
 #include "common/config.h"
 #include "common/Clock.h"
 #include "common/DecayCounter.h"
+#include "common/StackStringStream.h"
 #include "common/entity_name.h"
 
 #include "include/Context.h"
     } else {
       snprintf(b, sizeof(b), "%s", "head");
     }
-    std::ostringstream oss;
-    oss << name << "_" << b;
-    key = oss.str();
+    CachedStackStringStream css;
+    *css << name << "_" << b;
+    key = css->strv();
   }
   static void decode_helper(ceph::buffer::list::const_iterator& bl, std::string& nm,
                            snapid_t& sn) {
 
 inline std::ostream& operator<<(std::ostream& out, const dirfrag_load_vec_t& dl)
 {
-  std::ostringstream ss;
-  ss << std::setprecision(1) << std::fixed
+  CachedStackStringStream css;
+  *css << std::setprecision(1) << std::fixed
      << "[pop"
         " IRD:" << dl.vec[0]
      << " IWR:" << dl.vec[1]
      << " FET:" << dl.vec[3]
      << " STR:" << dl.vec[4]
      << " *LOAD:" << dl.meta_load() << "]";
-  return out << ss.str() << std::endl;
+  return out << css->strv() << std::endl;
 }
 
 struct mds_load_t {