[Pkg-ceph-commits] [ceph] 01/01: Patchworks
Dmitry Smirnov
onlyjob at moszumanska.debian.org
Sat Nov 15 16:31:22 UTC 2014
This is an automated email from the git hooks/post-receive script.
onlyjob pushed a commit to branch experimental
in repository ceph.
commit 9a25bee (experimental)
Author: Dmitry Smirnov <onlyjob at member.fsf.org>
Date: Sat Nov 15 16:30:18 2014
Patchworks
---
debian/patches/0latest-giant.patch | 955 +++++++++++++++++++++++++++++++++++++
debian/patches/bug-10059.patch | 28 ++
debian/patches/bug-9341.patch | 107 -----
debian/patches/bug-9752.patch | 33 --
debian/patches/bug-9869.patch | 40 --
debian/patches/bug-9945.patch | 50 --
debian/patches/series | 6 +-
debian/patches/sleep-recover.patch | 2 +-
8 files changed, 986 insertions(+), 235 deletions(-)
diff --git a/debian/patches/0latest-giant.patch b/debian/patches/0latest-giant.patch
new file mode 100644
index 0000000..251cb02
--- /dev/null
+++ b/debian/patches/0latest-giant.patch
@@ -0,0 +1,955 @@
+Last-Update: 2014-11-15
+Forwarded: not-needed
+Origin: upstream
+Author: Dmitry Smirnov <onlyjob at member.fsf.org>
+Description: fixes from "Giant" branch since 0.87 release
+
+--- a/src/client/Client.cc
++++ b/src/client/Client.cc
+@@ -141,9 +141,9 @@
+ // -------------
+
+ dir_result_t::dir_result_t(Inode *in)
+ : inode(in), offset(0), this_offset(2), next_offset(2),
+- release_count(0), start_shared_gen(0),
++ release_count(0), ordered_count(0), start_shared_gen(0),
+ buffer(0) {
+ inode->get();
+ }
+
+@@ -505,17 +505,47 @@
+ inode_map.clear();
+ }
+ }
+
++void Client::trim_cache_for_reconnect(MetaSession *s)
++{
++ int mds = s->mds_num;
++ ldout(cct, 20) << "trim_cache_for_reconnect mds." << mds << dendl;
++
++ int trimmed = 0;
++ list<Dentry*> skipped;
++ while (lru.lru_get_size() > 0) {
++ Dentry *dn = static_cast<Dentry*>(lru.lru_expire());
++ if (!dn)
++ break;
++
++ if ((dn->inode && dn->inode->caps.count(mds)) ||
++ dn->dir->parent_inode->caps.count(mds)) {
++ trim_dentry(dn);
++ trimmed++;
++ } else
++ skipped.push_back(dn);
++ }
++
++ for(list<Dentry*>::iterator p = skipped.begin(); p != skipped.end(); ++p)
++ lru.lru_insert_mid(*p);
++
++ ldout(cct, 20) << "trim_cache_for_reconnect mds." << mds
++ << " trimmed " << trimmed << " dentries" << dendl;
++
++ if (s->caps.size() > 0)
++ _invalidate_kernel_dcache();
++}
++
+ void Client::trim_dentry(Dentry *dn)
+ {
+ ldout(cct, 15) << "trim_dentry unlinking dn " << dn->name
+ << " in dir " << hex << dn->dir->parent_inode->ino
+ << dendl;
++ dn->dir->release_count++;
+ if (dn->dir->parent_inode->flags & I_COMPLETE) {
+- ldout(cct, 10) << " clearing I_COMPLETE on " << *dn->dir->parent_inode << dendl;
+- dn->dir->parent_inode->flags &= ~I_COMPLETE;
+- dn->dir->release_count++;
++ ldout(cct, 10) << " clearing (I_COMPLETE|I_DIR_ORDERED) on " << *dn->dir->parent_inode << dendl;
++ dn->dir->parent_inode->flags &= ~(I_COMPLETE | I_DIR_ORDERED);
+ }
+ unlink(dn, false, false); // drop dir, drop dentry
+ }
+
+@@ -734,19 +764,19 @@
+ (st->cap.caps & CEPH_CAP_FILE_SHARED) &&
+ (issued & CEPH_CAP_FILE_EXCL) == 0 &&
+ in->dirstat.nfiles == 0 &&
+ in->dirstat.nsubdirs == 0) {
+- ldout(cct, 10) << " marking I_COMPLETE on empty dir " << *in << dendl;
+- in->flags |= I_COMPLETE;
++ ldout(cct, 10) << " marking (I_COMPLETE|I_DIR_ORDERED) on empty dir " << *in << dendl;
++ in->flags |= I_COMPLETE | I_DIR_ORDERED;
+ if (in->dir) {
+ ldout(cct, 10) << " dir is open on empty dir " << in->ino << " with "
+- << in->dir->dentry_map.size() << " entries, marking all dentries null" << dendl;
+- for (map<string, Dentry*>::iterator p = in->dir->dentry_map.begin();
+- p != in->dir->dentry_map.end();
++ << in->dir->dentry_list.size() << " entries, marking all dentries null" << dendl;
++ for (xlist<Dentry*>::iterator p = in->dir->dentry_list.begin();
++ !p.end();
+ ++p) {
+- unlink(p->second, true, true); // keep dir, keep dentry
++ unlink(*p, true, true); // keep dir, keep dentry
+ }
+- if (in->dir->dentry_map.empty())
++ if (in->dir->dentry_list.empty())
+ close_dir(in->dir);
+ }
+ }
+
+@@ -757,9 +787,9 @@
+ /*
+ * insert_dentry_inode - insert + link a single dentry + inode into the metadata cache.
+ */
+ Dentry *Client::insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dlease,
+- Inode *in, utime_t from, MetaSession *session, bool set_offset,
++ Inode *in, utime_t from, MetaSession *session,
+ Dentry *old_dentry)
+ {
+ Dentry *dn = NULL;
+ if (dir->dentries.count(dname))
+@@ -784,16 +814,26 @@
+ }
+
+ if (!dn || dn->inode == 0) {
+ in->get();
+- if (old_dentry)
++ if (old_dentry) {
++ if (old_dentry->dir != dir) {
++ old_dentry->dir->ordered_count++;
++ if (old_dentry->dir->parent_inode->flags & I_DIR_ORDERED) {
++ ldout(cct, 10) << " clearing I_DIR_ORDERED on "
++ << *old_dentry->dir->parent_inode << dendl;
++ old_dentry->dir->parent_inode->flags &= ~I_DIR_ORDERED;
++ }
++ }
+ unlink(old_dentry, dir == old_dentry->dir, false); // drop dentry, keep dir open if its the same dir
++ }
++ dir->ordered_count++;
++ if (dir->parent_inode->flags & I_DIR_ORDERED) {
++ ldout(cct, 10) << " clearing I_DIR_ORDERED on " << *dir->parent_inode << dendl;
++ dir->parent_inode->flags &= ~I_DIR_ORDERED;
++ }
+ dn = link(dir, dname, in, dn);
+ put_inode(in);
+- if (set_offset) {
+- ldout(cct, 15) << " setting dn offset to " << dir->max_offset << dendl;
+- dn->offset = dir->max_offset++;
+- }
+ }
+
+ update_dentry_lease(dn, dlease, from, session);
+ return dn;
+@@ -907,10 +947,8 @@
+ request->readdir_reply_frag = fg;
+ request->readdir_end = end;
+ request->readdir_num = numdn;
+
+- map<string,Dentry*>::iterator pd = dir->dentry_map.upper_bound(readdir_start);
+-
+ string dname;
+ LeaseStat dlease;
+ for (unsigned i=0; i<numdn; i++) {
+ ::decode(dname, p);
+@@ -918,46 +956,22 @@
+ InodeStat ist(p, features);
+
+ ldout(cct, 15) << "" << i << ": '" << dname << "'" << dendl;
+
+- // remove any skipped names
+- while (pd != dir->dentry_map.end() && pd->first < dname) {
+- if (pd->first < dname &&
+- fg.contains(diri->hash_dentry_name(pd->first))) { // do not remove items in earlier frags
+- Dentry *dn = pd->second;
+- if (dn->inode) {
+- ldout(cct, 15) << __func__ << " unlink '" << pd->first << "'" << dendl;
+- ++pd;
+- unlink(dn, true, true); // keep dir, dentry
+- } else {
+- ++pd;
+- }
+- } else {
+- ++pd;
+- }
+- }
+-
+- if (pd == dir->dentry_map.end())
+- ldout(cct, 15) << " pd is at end" << dendl;
+- else
+- ldout(cct, 15) << " pd is '" << pd->first << "' dn " << pd->second << dendl;
+-
+ Inode *in = add_update_inode(&ist, request->sent_stamp, session);
+ Dentry *dn;
+- if (pd != dir->dentry_map.end() &&
+- pd->first == dname) {
+- Dentry *olddn = pd->second;
+- if (pd->second->inode != in) {
++ if (diri->dir->dentries.count(dname)) {
++ Dentry *olddn = diri->dir->dentries[dname];
++ if (olddn->inode != in) {
+ // replace incorrect dentry
+- ++pd; // we are about to unlink this guy, move past it.
+ unlink(olddn, true, true); // keep dir, dentry
+ dn = link(dir, dname, in, olddn);
+ assert(dn == olddn);
+ } else {
+ // keep existing dn
+ dn = olddn;
+ touch_dn(dn);
+- ++pd; // move past the dentry we just touched.
++ dn->item_dentry_list.move_to_back();
+ }
+ } else {
+ // new dn
+ dn = link(dir, dname, in, NULL);
+@@ -972,21 +986,8 @@
+ ldout(cct, 15) << __func__ << " " << hex << dn->offset << dec << ": '" << dname << "' -> " << in->ino << dendl;
+ }
+ request->readdir_last_name = dname;
+
+- // remove trailing names
+- if (end) {
+- while (pd != dir->dentry_map.end()) {
+- if (fg.contains(diri->hash_dentry_name(pd->first))) {
+- ldout(cct, 15) << __func__ << " unlink '" << pd->first << "'" << dendl;
+- Dentry *dn = pd->second;
+- ++pd;
+- unlink(dn, true, true); // keep dir, dentry
+- } else
+- ++pd;
+- }
+- }
+-
+ if (dir->is_empty())
+ close_dir(dir);
+ }
+ }
+@@ -1014,13 +1015,14 @@
+ if (p.end()) {
+ ldout(cct, 10) << "insert_trace -- no trace" << dendl;
+
+ Dentry *d = request->dentry();
+- if (d && d->dir &&
+- (d->dir->parent_inode->flags & I_COMPLETE)) {
+- ldout(cct, 10) << " clearing I_COMPLETE on " << *d->dir->parent_inode << dendl;
+- d->dir->parent_inode->flags &= ~I_COMPLETE;
++ if (d && d->dir) {
+ d->dir->release_count++;
++ if (d->dir->parent_inode->flags & I_COMPLETE) {
++ ldout(cct, 10) << " clearing (I_COMPLETE|I_DIR_ORDERED) on " << *d->dir->parent_inode << dendl;
++ d->dir->parent_inode->flags &= ~(I_COMPLETE | I_DIR_ORDERED);
++ }
+ }
+
+ if (d && reply->get_result() == 0) {
+ if (request->head.op == CEPH_MDS_OP_RENAME) {
+@@ -1077,16 +1079,22 @@
+ update_dir_dist(diri, &dst); // dir stat info is attached to ..
+
+ if (in) {
+ Dir *dir = diri->open_dir();
+- insert_dentry_inode(dir, dname, &dlease, in, request->sent_stamp, session, true,
++ insert_dentry_inode(dir, dname, &dlease, in, request->sent_stamp, session,
+ ((request->head.op == CEPH_MDS_OP_RENAME) ?
+ request->old_dentry() : NULL));
+ } else {
+ if (diri->dir && diri->dir->dentries.count(dname)) {
+ Dentry *dn = diri->dir->dentries[dname];
+- if (dn->inode)
++ if (dn->inode) {
++ diri->dir->ordered_count++;
++ if (diri->flags & I_DIR_ORDERED) {
++ ldout(cct, 10) << " clearing I_DIR_ORDERED on " << *diri << dendl;
++ diri->flags &= ~I_DIR_ORDERED;
++ }
+ unlink(dn, true, true); // keep dir, dentry
++ }
+ }
+ }
+ } else if (reply->head.op == CEPH_MDS_OP_LOOKUPSNAP ||
+ reply->head.op == CEPH_MDS_OP_MKSNAP) {
+@@ -1103,9 +1111,9 @@
+ dlease.duration_ms = 0;
+
+ if (in) {
+ Dir *dir = diri->open_dir();
+- insert_dentry_inode(dir, dname, &dlease, in, request->sent_stamp, session, true);
++ insert_dentry_inode(dir, dname, &dlease, in, request->sent_stamp, session);
+ } else {
+ if (diri->dir && diri->dir->dentries.count(dname)) {
+ Dentry *dn = diri->dir->dentries[dname];
+ if (dn->inode)
+@@ -2051,10 +2059,15 @@
+ int newstate = mdsmap->get_state(p->first);
+ if (!mdsmap->is_up(p->first) ||
+ mdsmap->get_inst(p->first) != p->second->inst) {
+ p->second->con->mark_down();
+- if (mdsmap->is_up(p->first))
++ if (mdsmap->is_up(p->first)) {
+ p->second->inst = mdsmap->get_inst(p->first);
++ // When new MDS starts to take over, notify kernel to trim unused entries
++ // in its dcache/icache. Hopefully, the kernel will release some unused
++ // inodes before the new MDS enters reconnect state.
++ trim_cache_for_reconnect(p->second);
++ }
+ } else if (oldstate == newstate)
+ continue; // no change
+
+ if (newstate == MDSMap::STATE_RECONNECT &&
+@@ -2090,8 +2103,16 @@
+ {
+ int mds = session->mds_num;
+ ldout(cct, 10) << "send_reconnect to mds." << mds << dendl;
+
++ // trim unused caps to reduce MDS's cache rejoin time
++ trim_cache_for_reconnect(session);
++
++ if (session->release) {
++ session->release->put();
++ session->release = NULL;
++ }
++
+ MClientReconnect *m = new MClientReconnect;
+
+ // i have an open session.
+ ceph::unordered_set<inodeno_t> did_snaprealm;
+@@ -2295,16 +2316,17 @@
+
+ // link to dir
+ dn->dir = dir;
+ dir->dentries[dn->name] = dn;
+- dir->dentry_map[dn->name] = dn;
++ dir->dentry_list.push_back(&dn->item_dentry_list);
+ lru.lru_insert_mid(dn); // mid or top?
+
+ ldout(cct, 15) << "link dir " << dir->parent_inode << " '" << name << "' to inode " << in
+ << " dn " << dn << " (new dn)" << dendl;
+ } else {
+ ldout(cct, 15) << "link dir " << dir->parent_inode << " '" << name << "' to inode " << in
+ << " dn " << dn << " (old dn)" << dendl;
++ dn->item_dentry_list.move_to_back();
+ }
+
+ if (in) { // link to inode
+ dn->inode = in;
+@@ -2360,9 +2382,9 @@
+ ldout(cct, 15) << "unlink removing '" << dn->name << "' dn " << dn << dendl;
+
+ // unlink from dir
+ dn->dir->dentries.erase(dn->name);
+- dn->dir->dentry_map.erase(dn->name);
++ dn->item_dentry_list.remove_myself();
+ if (dn->dir->is_empty() && !keepdir)
+ close_dir(dn->dir);
+ dn->dir = 0;
+
+@@ -2514,13 +2536,25 @@
+ << " dropping " << ccap_string(dropping)
+ << dendl;
+
+ if (cct->_conf->client_inject_release_failure && revoking) {
++ const int would_have_issued = cap->issued & retain;
++ const int would_have_implemented = cap->implemented & (cap->issued | used);
+ // Simulated bug:
+ // - tell the server we think issued is whatever they issued plus whatever we implemented
+ // - leave what we have implemented in place
+ ldout(cct, 20) << __func__ << " injecting failure to release caps" << dendl;
+ cap->issued = cap->issued | cap->implemented;
++
++ // Make an exception for revoking xattr caps: we are injecting
++ // failure to release other caps, but allow xattr because client
++ // will block on xattr ops if it can't release these to MDS (#9800)
++ const int xattr_mask = CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
++ cap->issued ^= xattr_mask & revoking;
++ cap->implemented ^= xattr_mask & revoking;
++
++ ldout(cct, 20) << __func__ << " issued " << ccap_string(cap->issued) << " vs " << ccap_string(would_have_issued) << dendl;
++ ldout(cct, 20) << __func__ << " implemented " << ccap_string(cap->implemented) << " vs " << ccap_string(would_have_implemented) << dendl;
+ } else {
+ // Normal behaviour
+ cap->issued &= retain;
+ cap->implemented &= cap->issued | used;
+@@ -3028,10 +3062,10 @@
+ !(had & CEPH_CAP_FILE_SHARED)) {
+ in->shared_gen++;
+
+ if (in->is_dir() && (in->flags & I_COMPLETE)) {
+- ldout(cct, 10) << " clearing I_COMPLETE on " << *in << dendl;
+- in->flags &= ~I_COMPLETE;
++ ldout(cct, 10) << " clearing (I_COMPLETE|I_DIR_ORDERED) on " << *in << dendl;
++ in->flags &= ~(I_COMPLETE | I_DIR_ORDERED);
+ }
+ }
+ }
+
+@@ -3195,8 +3229,22 @@
+ }
+ sync_cond.Signal();
+ }
+
++void Client::_invalidate_kernel_dcache()
++{
++ // notify kernel to invalidate top level directory entries. As a side effect,
++ // unused inodes underneath these entries get pruned.
++ if (dentry_invalidate_cb && root->dir) {
++ for (ceph::unordered_map<string, Dentry*>::iterator p = root->dir->dentries.begin();
++ p != root->dir->dentries.end();
++ ++p) {
++ if (p->second->inode)
++ _schedule_invalidate_dentry_callback(p->second, false);
++ }
++ }
++}
++
+ void Client::trim_caps(MetaSession *s, int max)
+ {
+ int mds = s->mds_num;
+ ldout(cct, 10) << "trim_caps mds." << mds << " max " << max << dendl;
+@@ -3253,25 +3301,10 @@
+ }
+ }
+ s->s_cap_iterator = NULL;
+
+-
+- // notify kernel to invalidate top level directory entries. As a side effect,
+- // unused inodes underneath these entries get pruned.
+- if (dentry_invalidate_cb && s->caps.size() > max) {
+- assert(root);
+- if (root->dir) {
+- for (ceph::unordered_map<string, Dentry*>::iterator p = root->dir->dentries.begin();
+- p != root->dir->dentries.end();
+- ++p) {
+- if (p->second->inode)
+- _schedule_invalidate_dentry_callback(p->second, false);
+- }
+- } else {
+- // This seems unnatural, as long as we are holding caps they must be on
+- // some descendent of the root, so why don't we have the root open?
+- }
+- }
++ if (s->caps.size() > max)
++ _invalidate_kernel_dcache();
+ }
+
+ void Client::mark_caps_dirty(Inode *in, int caps)
+ {
+@@ -3793,11 +3826,12 @@
+ {
+ int mds = session->mds_num;
+ int dirty = m->get_dirty();
+ int cleaned = 0;
++ uint16_t flush_ack_tid = static_cast<uint16_t>(m->get_client_tid());
+ for (int i = 0; i < CEPH_CAP_BITS; ++i) {
+ if ((dirty & (1 << i)) &&
+- (m->get_client_tid() == in->flushing_cap_tid[i]))
++ (flush_ack_tid == in->flushing_cap_tid[i]))
+ cleaned |= 1 << i;
+ }
+
+ ldout(cct, 5) << "handle_cap_flush_ack mds." << mds
+@@ -5175,10 +5209,12 @@
+ if (!in->is_dir())
+ return -ENOTDIR;
+ *dirpp = new dir_result_t(in);
+ (*dirpp)->set_frag(in->dirfragtree[0]);
+- if (in->dir)
++ if (in->dir) {
+ (*dirpp)->release_count = in->dir->release_count;
++ (*dirpp)->ordered_count = in->dir->ordered_count;
++ }
+ (*dirpp)->start_shared_gen = in->shared_gen;
+ ldout(cct, 10) << "_opendir " << in->ino << ", our cache says the first dirfrag is " << (*dirpp)->frag() << dendl;
+ ldout(cct, 3) << "_opendir(" << in->ino << ") = " << 0 << " (" << *dirpp << ")" << dendl;
+ return 0;
+@@ -5405,35 +5441,40 @@
+ dirp->set_end();
+ return 0;
+ }
+
+- map<string,Dentry*>::iterator pd;
++ xlist<Dentry*>::iterator pd = dir->dentry_list.begin();
+ if (dirp->at_cache_name.length()) {
+- pd = dir->dentry_map.find(dirp->at_cache_name);
+- if (pd == dir->dentry_map.end())
+- return -EAGAIN; // weird, i give up
++ ceph::unordered_map<string,Dentry*>::iterator it = dir->dentries.find(dirp->at_cache_name);
++ if (it == dir->dentries.end())
++ return -EAGAIN;
++ Dentry *dn = it->second;
++ pd = xlist<Dentry*>::iterator(&dn->item_dentry_list);
+ ++pd;
+- } else {
+- pd = dir->dentry_map.begin();
+ }
+
+ string prev_name;
+- while (pd != dir->dentry_map.end()) {
+- Dentry *dn = pd->second;
++ while (!pd.end()) {
++ Dentry *dn = *pd;
+ if (dn->inode == NULL) {
+- ldout(cct, 15) << " skipping null '" << pd->first << "'" << dendl;
++ ldout(cct, 15) << " skipping null '" << dn->name << "'" << dendl;
++ ++pd;
++ continue;
++ }
++ if (dn->cap_shared_gen != dir->parent_inode->shared_gen) {
++ ldout(cct, 15) << " skipping mismatch shared gen '" << dn->name << "'" << dendl;
+ ++pd;
+ continue;
+ }
+
+ struct stat st;
+ struct dirent de;
+ int stmask = fill_stat(dn->inode, &st);
+- fill_dirent(&de, pd->first.c_str(), st.st_mode, st.st_ino, dirp->offset + 1);
++ fill_dirent(&de, dn->name.c_str(), st.st_mode, st.st_ino, dirp->offset + 1);
+
+ uint64_t next_off = dn->offset + 1;
+ ++pd;
+- if (pd == dir->dentry_map.end())
++ if (pd.end())
+ next_off = dir_result_t::END;
+
+ client_lock.Unlock();
+ int r = cb(p, &de, &st, stmask, next_off); // _next_ offset
+@@ -5528,14 +5569,15 @@
+ }
+
+ // can we read from our cache?
+ ldout(cct, 10) << "offset " << hex << dirp->offset << dec << " at_cache_name " << dirp->at_cache_name
+- << " snapid " << dirp->inode->snapid << " complete " << (bool)(dirp->inode->flags & I_COMPLETE)
++ << " snapid " << dirp->inode->snapid << " (complete && ordered) "
++ << dirp->inode->is_complete_and_ordered()
+ << " issued " << ccap_string(dirp->inode->caps_issued())
+ << dendl;
+ if ((dirp->offset == 2 || dirp->at_cache_name.length()) &&
+ dirp->inode->snapid != CEPH_SNAPDIR &&
+- (dirp->inode->flags & I_COMPLETE) &&
++ dirp->inode->is_complete_and_ordered() &&
+ dirp->inode->caps_issued_mask(CEPH_CAP_FILE_SHARED)) {
+ int err = _readdir_cache_cb(dirp, cb, p);
+ if (err != -EAGAIN)
+ return err;
+@@ -5600,14 +5642,17 @@
+ continue;
+ }
+
+ if (diri->dir &&
+- diri->dir->release_count == dirp->release_count &&
+- diri->shared_gen == dirp->start_shared_gen) {
+- ldout(cct, 10) << " marking I_COMPLETE on " << *diri << dendl;
+- diri->flags |= I_COMPLETE;
+- if (diri->dir)
+- diri->dir->max_offset = dirp->offset;
++ diri->shared_gen == dirp->start_shared_gen &&
++ diri->dir->release_count == dirp->release_count) {
++ if (diri->dir->ordered_count == dirp->ordered_count) {
++ ldout(cct, 10) << " marking (I_COMPLETE|I_DIR_ORDERED) on " << *diri << dendl;
++ diri->flags |= I_COMPLETE | I_DIR_ORDERED;
++ } else {
++ ldout(cct, 10) << " marking I_COMPLETE on " << *diri << dendl;
++ diri->flags |= I_COMPLETE;
++ }
+ }
+
+ dirp->set_end();
+ return 0;
+--- a/src/client/Client.h
++++ b/src/client/Client.h
+@@ -154,8 +154,9 @@
+ uint64_t next_offset; // offset of next chunk (last_name's + 1)
+ string last_name; // last entry in previous chunk
+
+ uint64_t release_count;
++ uint64_t ordered_count;
+ int start_shared_gen; // dir shared_gen at start of readdir
+
+ frag_t buffer_frag;
+ vector<pair<string,Inode*> > *buffer;
+@@ -400,10 +401,12 @@
+ void touch_dn(Dentry *dn);
+
+ // trim cache.
+ void trim_cache();
++ void trim_cache_for_reconnect(MetaSession *s);
+ void trim_dentry(Dentry *dn);
+ void trim_caps(MetaSession *s, int max);
++ void _invalidate_kernel_dcache();
+
+ void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
+ void dump_cache(Formatter *f); // debug
+
+@@ -533,9 +536,9 @@
+ version_t inline_version, bufferlist& inline_data,
+ int issued);
+ Inode *add_update_inode(InodeStat *st, utime_t ttl, MetaSession *session);
+ Dentry *insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dlease,
+- Inode *in, utime_t from, MetaSession *session, bool set_offset,
++ Inode *in, utime_t from, MetaSession *session,
+ Dentry *old_dentry = NULL);
+ void update_dentry_lease(Dentry *dn, LeaseStat *dlease, utime_t from, MetaSession *session);
+
+
+--- a/src/client/Dentry.h
++++ b/src/client/Dentry.h
+@@ -1,8 +1,9 @@
+ #ifndef CEPH_CLIENT_DENTRY_H
+ #define CEPH_CLIENT_DENTRY_H
+
+ #include "include/lru.h"
++#include "include/xlist.h"
+
+ class Dir;
+ struct Inode;
+
+@@ -19,8 +20,10 @@
+ uint64_t lease_gen;
+ ceph_seq_t lease_seq;
+ int cap_shared_gen;
+
++ xlist<Dentry*>::item item_dentry_list;
++
+ /*
+ * ref==1 -> cached, unused
+ * ref >1 -> pinned in lru
+ */
+@@ -40,9 +43,12 @@
+ }
+
+ void dump(Formatter *f) const;
+
+- Dentry() : dir(0), inode(0), ref(1), offset(0), lease_mds(-1), lease_gen(0), lease_seq(0), cap_shared_gen(0) { }
++ Dentry() :
++ dir(0), inode(0), ref(1), offset(0),
++ lease_mds(-1), lease_gen(0), lease_seq(0), cap_shared_gen(0),
++ item_dentry_list(this) { }
+ private:
+ ~Dentry() {
+ assert(ref == 0);
+ }
+--- a/src/client/Dir.h
++++ b/src/client/Dir.h
+@@ -6,13 +6,13 @@
+ class Dir {
+ public:
+ Inode *parent_inode; // my inode
+ ceph::unordered_map<string, Dentry*> dentries;
+- map<string, Dentry*> dentry_map;
++ xlist<Dentry*> dentry_list;
+ uint64_t release_count;
+- uint64_t max_offset;
++ uint64_t ordered_count;
+
+- Dir(Inode* in) : release_count(0), max_offset(2) { parent_inode = in; }
++ Dir(Inode* in) : release_count(0), ordered_count(0) { parent_inode = in; }
+
+ bool is_empty() { return dentries.empty(); }
+ };
+
+--- a/src/client/Inode.h
++++ b/src/client/Inode.h
+@@ -69,8 +69,9 @@
+
+
+ // inode flags
+ #define I_COMPLETE 1
++#define I_DIR_ORDERED 2
+
+ struct Inode {
+ CephContext *cct;
+
+@@ -133,8 +134,13 @@
+ }
+
+ unsigned flags;
+
++ bool is_complete_and_ordered() {
++ static const unsigned wants = I_COMPLETE | I_DIR_ORDERED;
++ return (flags & wants) == wants;
++ }
++
+ // about the dir (if this is one!)
+ set<int> dir_contacts;
+ bool dir_hashed, dir_replicated;
+
+--- a/src/common/config.cc
++++ b/src/common/config.cc
+@@ -946,9 +946,9 @@
+ return -ENOSYS;
+ }
+
+ static const char *CONF_METAVARIABLES[] =
+- { "cluster", "type", "name", "host", "num", "id", "pid" };
++ { "cluster", "type", "name", "host", "num", "id", "pid", "cctid" };
+ static const int NUM_CONF_METAVARIABLES =
+ (sizeof(CONF_METAVARIABLES) / sizeof(CONF_METAVARIABLES[0]));
+
+ void md_config_t::expand_all_meta()
+@@ -1058,8 +1058,10 @@
+ else if (var == "id")
+ out += name.get_id().c_str();
+ else if (var == "pid")
+ out += stringify(getpid());
++ else if (var == "cctid")
++ out += stringify((unsigned long long)this);
+ else
+ assert(0); // unreachable
+ expanded = true;
+ }
+--- a/src/messages/MClientSession.h
++++ b/src/messages/MClientSession.h
+@@ -18,8 +18,9 @@
+ #include "msg/Message.h"
+
+ class MClientSession : public Message {
+ static const int HEAD_VERSION = 2;
++ static const int COMPAT_VERSION = 1;
+
+ public:
+ ceph_mds_session_head head;
+
+@@ -30,17 +31,17 @@
+ utime_t get_stamp() const { return utime_t(head.stamp); }
+ int get_max_caps() const { return head.max_caps; }
+ int get_max_leases() const { return head.max_leases; }
+
+- MClientSession() : Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION) { }
++ MClientSession() : Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) { }
+ MClientSession(int o, version_t s=0) :
+- Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION) {
++ Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ head.seq = s;
+ }
+ MClientSession(int o, utime_t st) :
+- Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION) {
++ Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) {
+ memset(&head, 0, sizeof(head));
+ head.op = o;
+ head.seq = 0;
+ st.encode_timeval(&head.stamp);
+--- a/src/mon/Monitor.cc
++++ b/src/mon/Monitor.cc
+@@ -1582,8 +1582,10 @@
+ * @todo fix this. This is going to cause trouble.
+ */
+ void Monitor::handle_probe_probe(MMonProbe *m)
+ {
++ MMonProbe *r;
++
+ dout(10) << "handle_probe_probe " << m->get_source_inst() << *m
+ << " features " << m->get_connection()->get_features() << dendl;
+ uint64_t missing = required_features & ~m->get_connection()->get_features();
+ if (missing) {
+@@ -1594,14 +1596,28 @@
+ name, has_ever_joined);
+ m->required_features = required_features;
+ m->get_connection()->send_message(r);
+ }
+- m->put();
+- return;
++ goto out;
++ }
++
++ if (!is_probing() && !is_synchronizing()) {
++ // If the probing mon is way ahead of us, we need to re-bootstrap.
++ // Normally we capture this case when we initially bootstrap, but
++ // it is possible we pass those checks (we overlap with
++ // quorum-to-be) but fail to join a quorum before it moves past
++ // us. We need to be kicked back to bootstrap so we can
++ // synchonize, not keep calling elections.
++ if (paxos->get_version() + 1 < m->paxos_first_version) {
++ dout(1) << " peer " << m->get_source_addr() << " has first_committed "
++ << "ahead of us, re-bootstrapping" << dendl;
++ bootstrap();
++ goto out;
++
++ }
+ }
+
+- MMonProbe *r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY,
+- name, has_ever_joined);
++ r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY, name, has_ever_joined);
+ r->name = name;
+ r->quorum = quorum;
+ monmap->encode(r->monmap_bl, m->get_connection()->get_features());
+ r->paxos_first_version = paxos->get_first_committed();
+@@ -1614,8 +1630,9 @@
+ << " to list of hints" << dendl;
+ extra_probe_peers.insert(m->get_source_addr());
+ }
+
++ out:
+ m->put();
+ }
+
+ void Monitor::handle_probe_reply(MMonProbe *m)
+--- a/src/mon/Paxos.cc
++++ b/src/mon/Paxos.cc
+@@ -464,9 +464,9 @@
+ // commit and need to push it to them.
+ peer_first_committed[from] = last->first_committed;
+ peer_last_committed[from] = last->last_committed;
+
+- if (last->first_committed > last_committed+1) {
++ if (last->first_committed > last_committed + 1) {
+ dout(5) << __func__
+ << " mon." << from
+ << " lowest version is too high for our last committed"
+ << " (theirs: " << last->first_committed
+@@ -486,9 +486,9 @@
+ // is everyone contiguous and up to date?
+ for (map<int,version_t>::iterator p = peer_last_committed.begin();
+ p != peer_last_committed.end();
+ ++p) {
+- if (p->second < first_committed && first_committed > 1) {
++ if (p->second + 1 < first_committed && first_committed > 1) {
+ dout(5) << __func__
+ << " peon " << p->first
+ << " last_committed (" << p->second
+ << ") is too low for our first_committed (" << first_committed
+--- a/src/osd/OSD.cc
++++ b/src/osd/OSD.cc
+@@ -8094,10 +8094,10 @@
+
+ OSDMapRef send_map = service.try_get_map(m->get_map_epoch());
+ // check send epoch
+ if (!send_map) {
+-
+- dout(7) << "don't have sender's osdmap; assuming it was valid and that client will resend" << dendl;
++ dout(7) << "don't have sender's osdmap; assuming it was valid and that"
++ << " client will resend" << dendl;
+ return;
+ }
+ if (!send_map->have_pg_pool(pgid.pool())) {
+ dout(7) << "dropping request; pool did not exist" << dendl;
+@@ -8108,9 +8108,10 @@
+ << ", client e" << m->get_map_epoch()
+ << " when pool " << m->get_pg().pool() << " did not exist"
+ << "\n";
+ return;
+- } else if (send_map->get_pg_acting_role(pgid.pgid, whoami) < 0) {
++ }
++ if (!send_map->osd_is_valid_op_target(pgid.pgid, whoami)) {
+ dout(7) << "we are invalid target" << dendl;
+ clog->warn() << m->get_source_inst() << " misdirected " << m->get_reqid()
+ << " pg " << m->get_pg()
+ << " to osd." << whoami
+@@ -8124,10 +8125,11 @@
+ }
+
+ // check against current map too
+ if (!osdmap->have_pg_pool(pgid.pool()) ||
+- osdmap->get_pg_acting_role(pgid.pgid, whoami) < 0) {
+- dout(7) << "dropping; no longer have PG (or pool); client will retarget" << dendl;
++ !osdmap->osd_is_valid_op_target(pgid.pgid, whoami)) {
++ dout(7) << "dropping; no longer have PG (or pool); client will retarget"
++ << dendl;
+ return;
+ }
+
+ PG *pg = get_pg_or_queue_for_pg(pgid, op);
+--- a/src/osd/OSDMap.h
++++ b/src/osd/OSDMap.h
+@@ -770,8 +770,20 @@
+ int nrep = pg_to_acting_osds(pg, group);
+ return calc_pg_role(osd, group, nrep);
+ }
+
++ bool osd_is_valid_op_target(pg_t pg, int osd) const {
++ int primary;
++ vector<int> group;
++ int nrep = pg_to_acting_osds(pg, &group, &primary);
++ if (osd == primary)
++ return true;
++ if (pg_is_ec(pg))
++ return false;
++
++ return calc_pg_role(osd, group, nrep) >= 0;
++ }
++
+
+ /*
+ * handy helpers to build simple maps...
+ */
+--- a/src/osd/osd_types.cc
++++ b/src/osd/osd_types.cc
+@@ -2302,11 +2302,11 @@
+ f->close_section();
+ f->open_array_section("acting");
+ for (vector<int>::const_iterator p = acting.begin(); p != acting.end(); ++p)
+ f->dump_int("osd", *p);
++ f->close_section();
+ f->dump_int("primary", primary);
+ f->dump_int("up_primary", up_primary);
+- f->close_section();
+ }
+
+ void pg_interval_t::generate_test_instances(list<pg_interval_t*>& o)
+ {
+--- a/src/rgw/rgw_swift.cc
++++ b/src/rgw/rgw_swift.cc
+@@ -507,8 +507,10 @@
+ url.append(token);
+
+ validate.append_header("X-Auth-Token", admin_token);
+
++ validate.set_send_length(0);
++
+ int ret = validate.process(url.c_str());
+ if (ret < 0)
+ return ret;
+ }
+--- a/src/tools/cephfs/Dumper.cc
++++ b/src/tools/cephfs/Dumper.cc
+@@ -158,9 +158,9 @@
+
+ cout << "start " << start << " len " << len << std::endl;
+
+ Journaler::Header h;
+- h.trimmed_pos = start;
++ h.trimmed_pos = start - (start % g_default_file_layout.fl_object_size);
+ h.expire_pos = start;
+ h.write_pos = write_pos;
+ h.stream_format = format;
+ h.magic = CEPH_FS_ONDISK_MAGIC;
+--- a/src/tools/cephfs/JournalScanner.cc
++++ b/src/tools/cephfs/JournalScanner.cc
+@@ -153,12 +153,19 @@
+ bufferlist read_buf;
+ bool gap = false;
+ uint64_t gap_start = -1;
+ for (uint64_t obj_offset = (read_offset / object_size); ; obj_offset++) {
++ uint64_t offset_in_obj = 0;
++ if (obj_offset * object_size < header->expire_pos) {
++ // Skip up to expire_pos from start of the object
++ // (happens for the first object we read)
++ offset_in_obj = header->expire_pos - obj_offset * object_size;
++ }
++
+ // Read this journal segment
+ bufferlist this_object;
+ std::string const oid = obj_name(obj_offset);
+- r = io.read(oid, this_object, INT_MAX, 0);
++ r = io.read(oid, this_object, INT_MAX, offset_in_obj);
+
+ // Handle absent journal segments
+ if (r < 0) {
+ if (obj_offset > (header->write_pos / object_size)) {
+--- a/src/tools/rados/rados.cc
++++ b/src/tools/rados/rados.cc
+@@ -430,12 +430,11 @@
+ cerr << "error reading input file " << infile << ": " << cpp_strerror(ret) << std::endl;
+ goto out;
+ }
+ if (count == 0) {
+- if (!offset) {
+- ret = io_ctx.create(oid, true);
++ if (!offset) { // in case we have to create an empty object
++ ret = io_ctx.write_full(oid, indata); // indata is empty
+ if (ret < 0) {
+- cerr << "WARNING: could not create object: " << oid << std::endl;
+ goto out;
+ }
+ }
+ continue;
diff --git a/debian/patches/bug-10059.patch b/debian/patches/bug-10059.patch
new file mode 100644
index 0000000..9b28e1a
--- /dev/null
+++ b/debian/patches/bug-10059.patch
@@ -0,0 +1,28 @@
+commit c87bde6
+Author: Samuel Just <sjust at redhat.com>
+Date: Sat Nov 15 10:44:20 2014
+
+ PG: always clear_primary_state when leaving Primary
+
+ Otherwise, entries from the log collection process might leak into the next
+ epoch, where we might end up choosing a different authoritative log. In this
+ case, it resulted in us not rolling back to log entries on one of the replicas
+ prior to trying to recover from an affected object due to the peer_missing not
+ being cleared.
+
+ Fixes: #10059
+ Backport: giant, firefly, dumpling
+ Signed-off-by: Samuel Just <sjust at redhat.com>
+
+--- a/src/osd/PG.cc
++++ b/src/osd/PG.cc
+@@ -5533,8 +5533,9 @@
+ PG *pg = context< RecoveryMachine >().pg;
+ pg->want_acting.clear();
+ utime_t dur = ceph_clock_now(pg->cct) - enter_time;
+ pg->osd->recoverystate_perf->tinc(rs_primary_latency, dur);
++ pg->clear_primary_state();
+ }
+
+ /*---------Peering--------*/
+ PG::RecoveryState::Peering::Peering(my_context ctx)
diff --git a/debian/patches/bug-9341.patch b/debian/patches/bug-9341.patch
deleted file mode 100644
index 58e81ad..0000000
--- a/debian/patches/bug-9341.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-Last-update: 2014-10-20
-Forwarded: not-needed
-Origin: upstream, http://tracker.ceph.com/attachments/download/1388/0001-client-trim-unused-inodes-before-reconnecting-to-rec.patch
-Bug-Ceph: http://tracker.ceph.com/issues/9341
-From: Yan, Zheng <zyan at redhat.com>
-Description: dramatically (e.g seconds instead of hours) reduce rejoin (i.e. MDS restart) time.
-
---- a/src/client/Client.cc
-+++ b/src/client/Client.cc
-@@ -479,16 +479,21 @@
-
- // ===================
- // metadata cache stuff
-
--void Client::trim_cache()
-+void Client::trim_cache(unsigned max)
- {
-- ldout(cct, 20) << "trim_cache size " << lru.lru_get_size() << " max " << lru.lru_get_max() << dendl;
-+ if (max > lru.lru_get_max())
-+ max = lru.lru_get_max();
-+
-+ ldout(cct, 20) << "trim_cache size " << lru.lru_get_size() << " max " << max << dendl;
-+
- unsigned last = 0;
- while (lru.lru_get_size() != last) {
- last = lru.lru_get_size();
-
-- if (lru.lru_get_size() <= lru.lru_get_max()) break;
-+ if (lru.lru_get_size() <= max)
-+ break;
-
- // trim!
- Dentry *dn = static_cast<Dentry*>(lru.lru_expire());
- if (!dn)
-@@ -496,8 +501,24 @@
-
- trim_dentry(dn);
- }
-
-+ // notify kernel to invalidate top level directory entries. As a side effect,
-+ // unused inodes underneath these entries get pruned.
-+ if (dentry_invalidate_cb && lru.lru_get_size() > max) {
-+ if (root->dir) {
-+ for (ceph::unordered_map<string, Dentry*>::iterator p = root->dir->dentries.begin();
-+ p != root->dir->dentries.end();
-+ ++p) {
-+ if (p->second->inode)
-+ _schedule_invalidate_dentry_callback(p->second, false);
-+ }
-+ } else {
-+ // This seems unnatural, as long as we are holding caps they must be on
-+ // some descendent of the root, so why don't we have the root open?`
-+ }
-+ }
-+
- // hose root?
- if (lru.lru_get_size() == 0 && root && root->get_num_ref() == 0 && inode_map.size() == 1) {
- ldout(cct, 15) << "trim_cache trimmed root " << root << dendl;
- delete root;
-@@ -2051,10 +2072,15 @@
- int newstate = mdsmap->get_state(p->first);
- if (!mdsmap->is_up(p->first) ||
- mdsmap->get_inst(p->first) != p->second->inst) {
- p->second->con->mark_down();
-- if (mdsmap->is_up(p->first))
-- p->second->inst = mdsmap->get_inst(p->first);
-+ if (mdsmap->is_up(p->first)) {
-+ p->second->inst = mdsmap->get_inst(p->first);
-+ // When new MDS starts to take over, notify kernel to trim unused entries
-+ // in its dcache/icache. Hopefully, the kernel will release some unused
-+ // inodes before the new MDS enters reconnect state.
-+ trim_cache(1);
-+ }
- } else if (oldstate == newstate)
- continue; // no change
-
- if (newstate == MDSMap::STATE_RECONNECT &&
-@@ -2090,8 +2116,16 @@
- {
- int mds = session->mds_num;
- ldout(cct, 10) << "send_reconnect to mds." << mds << dendl;
-
-+ // trim unused caps to reduce MDS's cache rejoin time
-+ trim_cache(1);
-+
-+ if (session->release) {
-+ session->release->put();
-+ session->release = NULL;
-+ }
-+
- MClientReconnect *m = new MClientReconnect;
-
- // i have an open session.
- ceph::unordered_set<inodeno_t> did_snaprealm;
---- a/src/client/Client.h
-+++ b/src/client/Client.h
-@@ -399,9 +399,9 @@
- int fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat=0, nest_info_t *rstat=0);
- void touch_dn(Dentry *dn);
-
- // trim cache.
-- void trim_cache();
-+ void trim_cache(unsigned max=-1U);
- void trim_dentry(Dentry *dn);
- void trim_caps(MetaSession *s, int max);
-
- void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
diff --git a/debian/patches/bug-9752.patch b/debian/patches/bug-9752.patch
deleted file mode 100644
index 490bc29..0000000
--- a/debian/patches/bug-9752.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From e0b04414b92018277a0d3b9d82e72ea7529f4ef5 Mon Sep 17 00:00:00 2001
-From: Loic Dachary <loic-201408 at dachary.org>
-Date: Fri, 31 Oct 2014 00:49:21 +0100
-Subject: [PATCH] osd: past_interval display bug on acting
-
-The acting array was incorrectly including the primary and up_primary.
-
-http://tracker.ceph.com/issues/9752 Fixes: #9752
-
-Signed-off-by: Loic Dachary <loic-201408 at dachary.org>
-(cherry picked from commit c5f8d6eded52da451fdd1d807bd4700221e4c41c)
----
- src/osd/osd_types.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc
-index ed06c4f..dc9caa5 100644
---- a/src/osd/osd_types.cc
-+++ b/src/osd/osd_types.cc
-@@ -2303,9 +2303,9 @@ void pg_interval_t::dump(Formatter *f) const
- f->open_array_section("acting");
- for (vector<int>::const_iterator p = acting.begin(); p != acting.end(); ++p)
- f->dump_int("osd", *p);
-+ f->close_section();
- f->dump_int("primary", primary);
- f->dump_int("up_primary", up_primary);
-- f->close_section();
- }
-
- void pg_interval_t::generate_test_instances(list<pg_interval_t*>& o)
---
-2.1.1
-
diff --git a/debian/patches/bug-9869.patch b/debian/patches/bug-9869.patch
deleted file mode 100644
index c2c4ae9..0000000
--- a/debian/patches/bug-9869.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 905aba2f3d847933f98124f3ea8d1d76d644edb4 Mon Sep 17 00:00:00 2001
-From: Greg Farnum <greg at inktank.com>
-Date: Wed, 22 Oct 2014 17:16:31 -0700
-Subject: [PATCH] client: cast m->get_client_tid() to compare to 16-bit
- Inode::flushing_cap_tid
-
-m->get_client_tid() is 64 bits (as it should be), but Inode::flushing_cap_tid
-is only 16 bits. 16 bits should be plenty to let the cap flush updates
-pipeline appropriately, but we need to cast in the proper direction when
-comparing these differently-sized versions. So downcast the 64-bit one
-to 16 bits.
-
-Fixes: #9869
-Backport: giant, firefly, dumpling
-
-Signed-off-by: Greg Farnum <greg at inktank.com>
-(cherry picked from commit a5184cf46a6e867287e24aeb731634828467cd98)
----
- src/client/Client.cc | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/client/Client.cc b/src/client/Client.cc
-index 48e5400..ec3a232 100644
---- a/src/client/Client.cc
-+++ b/src/client/Client.cc
-@@ -3794,9 +3794,10 @@ void Client::handle_cap_flush_ack(MetaSession *session, Inode *in, Cap *cap, MCl
- int mds = session->mds_num;
- int dirty = m->get_dirty();
- int cleaned = 0;
-+ uint16_t flush_ack_tid = static_cast<uint16_t>(m->get_client_tid());
- for (int i = 0; i < CEPH_CAP_BITS; ++i) {
- if ((dirty & (1 << i)) &&
-- (m->get_client_tid() == in->flushing_cap_tid[i]))
-+ (flush_ack_tid == in->flushing_cap_tid[i]))
- cleaned |= 1 << i;
- }
-
---
-2.1.1
-
diff --git a/debian/patches/bug-9945.patch b/debian/patches/bug-9945.patch
deleted file mode 100644
index c9a75a3..0000000
--- a/debian/patches/bug-9945.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From b704f0dd888aacb10c32cdb63cdbf9f06296fc18 Mon Sep 17 00:00:00 2001
-From: John Spray <john.spray at redhat.com>
-Date: Thu, 30 Oct 2014 16:43:21 +0000
-Subject: [PATCH] messages: fix COMPAT_VERSION on MClientSession
-
-This was incorrectly incremented to 2 by omission
-of an explicit COMPAT_VERSION value.
-
-Fixes: #9945
-
-Signed-off-by: John Spray <john.spray at redhat.com>
-(cherry picked from commit 1eb9bcb1d36014293efc687b4331be8c4d208d8e)
----
- src/messages/MClientSession.h | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/src/messages/MClientSession.h b/src/messages/MClientSession.h
-index 0924189..3ef28e9 100644
---- a/src/messages/MClientSession.h
-+++ b/src/messages/MClientSession.h
-@@ -19,6 +19,7 @@
-
- class MClientSession : public Message {
- static const int HEAD_VERSION = 2;
-+ static const int COMPAT_VERSION = 1;
-
- public:
- ceph_mds_session_head head;
-@@ -31,15 +32,15 @@ public:
- int get_max_caps() const { return head.max_caps; }
- int get_max_leases() const { return head.max_leases; }
-
-- MClientSession() : Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION) { }
-+ MClientSession() : Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) { }
- MClientSession(int o, version_t s=0) :
-- Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION) {
-+ Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) {
- memset(&head, 0, sizeof(head));
- head.op = o;
- head.seq = s;
- }
- MClientSession(int o, utime_t st) :
-- Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION) {
-+ Message(CEPH_MSG_CLIENT_SESSION, HEAD_VERSION, COMPAT_VERSION) {
- memset(&head, 0, sizeof(head));
- head.op = o;
- head.seq = 0;
---
-2.1.1
-
diff --git a/debian/patches/series b/debian/patches/series
index 1f69b95..6f9791d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,9 +1,7 @@
## Backported / Upstream
-bug-9341.patch
-bug-9752.patch
+0latest-giant.patch
bug-9814.patch
-bug-9869.patch
-bug-9945.patch
+bug-10059.patch
sleep-recover.patch
## Debian
diff --git a/debian/patches/sleep-recover.patch b/debian/patches/sleep-recover.patch
index e7c02d4..09865d1 100644
--- a/debian/patches/sleep-recover.patch
+++ b/debian/patches/sleep-recover.patch
@@ -6,7 +6,7 @@ Description: fix fuse-client hang after wake-up from suspend.
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
-@@ -9359,8 +9359,9 @@
+@@ -9370,8 +9370,9 @@
case MetaSession::STATE_OPEN:
ldout(cct, 1) << "reset from mds we were open; mark session as stale" << dendl;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ceph/ceph.git
More information about the Pkg-ceph-commits
mailing list