From: Yan, Zheng Date: Mon, 16 Mar 2015 10:44:49 +0000 (+0800) Subject: mds: don't crash MDS when snapshot data not found X-Git-Tag: v9.0.0~150^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0dfab5d6390b2d5bec8213bbd7755dd3a643d6dd;p=ceph.git mds: don't crash MDS when snapshot data not found When remote dentry and inode are in different snapshot realms. The inode may not contain snapshot data for snapshot of the remote dentry. This issue are difficult to fix. This patch MDS print an error instead of triggering assersion. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 46eefad13531..8309c88e078b 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2981,26 +2981,36 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session, map *pxattrs = 0; - if (snapid != CEPH_NOSNAP && is_multiversion()) { + if (snapid != CEPH_NOSNAP) { // for now at least, old_inodes is only defined/valid on the auth if (!is_auth()) valid = false; - compact_map::iterator p = old_inodes.lower_bound(snapid); - if (p != old_inodes.end()) { - if (p->second.first > snapid) { - if (p != old_inodes.begin()) - --p; - else dout(0) << "old_inode lower_bound starts after snapid!" << dendl; + if (is_multiversion()) { + compact_map::iterator p = old_inodes.lower_bound(snapid); + if (p != old_inodes.end()) { + if (p->second.first > snapid) { + if (p != old_inodes.begin()) + --p; + } + if (p->second.first <= snapid && snapid <= p->first) { + dout(15) << "encode_inodestat snapid " << snapid + << " to old_inode [" << p->second.first << "," << p->first << "]" + << " " << p->second.inode.rstat + << dendl; + pi = oi = &p->second.inode; + pxattrs = &p->second.xattrs; + } else { + // snapshoted remote dentry can result this + dout(0) << "encode_inodestat old_inode for snapid " << snapid + << " not found" << dendl; + } } - dout(15) << "encode_inodestat snapid " << snapid - << " to old_inode [" << p->second.first << "," << p->first << "]" - << " " << p->second.inode.rstat - << dendl; - assert(p->second.first <= snapid && snapid <= p->first); - pi = oi = &p->second.inode; - pxattrs = &p->second.xattrs; + } else if (snapid < first || snapid > last) { + // snapshoted remote dentry can result this + dout(0) << "encode_inodestat [" << first << "," << last << "]" + << " not match snapid " << snapid << dendl; } }