diff options
author | Greg Farnum <greg@inktank.com> | 2013-02-22 15:04:34 -0800 |
---|---|---|
committer | Greg Farnum <greg@inktank.com> | 2013-02-22 19:57:53 -0800 |
commit | 525e12bbc2aed72c53528d6bd7f993d5477e85ef (patch) | |
tree | f1292bdfbe9ee9edad2200b91283aadb45f7edf5 | |
parent | dc181224abf6fb8fc583730ae3d90acdf0b80f39 (diff) | |
download | ceph-wip-4248-snapid-journaling.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.cc | 5 |
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 |