summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Farnum <greg@inktank.com>2013-02-22 15:04:34 -0800
committerGreg Farnum <greg@inktank.com>2013-02-22 19:57:53 -0800
commit525e12bbc2aed72c53528d6bd7f993d5477e85ef (patch)
treef1292bdfbe9ee9edad2200b91283aadb45f7edf5
parentdc181224abf6fb8fc583730ae3d90acdf0b80f39 (diff)
downloadceph-525e12bbc2aed72c53528d6bd7f993d5477e85ef.tar.gz
mds: update CInode snapids (first & last) during replaywip-4248-snapid-journaling
A user reported on the mailing list that they were hitting the assert assert(in->first == p->dnfirst || (in->is_multiversion() && in->first > p->dnfirst)); in EMetablob::replay. It turned out that it was on an unlink operation (which moved the inode into a straydir), and the stray dentry had a first of 4 while the inode had a first of 2. Investigation revealed that we weren't updating "first" or "last" of the CInode for any CInodes that existed in cache before the replay! (Non-existent inodes had the correct values set from the p->dnfirst and p->dnlast on construction). To fix this, we modify EMetaBlob::fullbit::update_inode() so that, *if* old_inodes is non-empty, we set in->first as 1 past the last entry's "last" value. This is good because old_inodes will have been modified any time the inode was (assuming it was already multi-version). Signed-off-by: Greg Farnum <greg@inktank.com>
-rw-r--r--src/mds/journal.cc5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/mds/journal.cc b/src/mds/journal.cc
index 09072cef0d8..e19b5c5a179 100644
--- a/src/mds/journal.cc
+++ b/src/mds/journal.cc
@@ -516,6 +516,11 @@ void EMetaBlob::fullbit::update_inode(MDS *mds, CInode *in)
in->symlink = symlink;
}
in->old_inodes = old_inodes;
+ if (!in->old_inodes.empty()) {
+ map<snapid_t, old_inode_t>::iterator p = in->old_inodes.end();
+ --p; // get the actual last entry
+ in->first = p->first + 1;
+ }
}
// EMetaBlob::remotebit