From 4cf342a13a82d3812149b737b89d276dbae02a3d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 2 Jun 2011 13:14:48 -0700 Subject: [PATCH] mds: pin inode while one renamed_files list Make sure the inode is pinned while it is on the LogSegment::renamed_files list. Avoids a crash when an inode on that list is wrongly trimmed. Signed-off-by: Sage Weil --- src/mds/CDir.cc | 1 + src/mds/CInode.cc | 17 +++++++++++------ src/mds/CInode.h | 2 ++ src/mds/Server.cc | 9 +++++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index efa4962b0eba4..d7390d8e62bcc 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1997,6 +1997,7 @@ void CDir::_committed(version_t v, version_t lrv) lrv == inode->inode.last_renamed_version) { inode->item_renamed_file.remove_myself(); inode->state_clear(CInode::STATE_DIRTYPARENT); + inode->put(CInode::PIN_DIRTYPARENT); dout(10) << "_committed stored parent pointer, removed from renamed_files list " << *inode << dendl; } diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 321ec01f04e60..76b0d964612d4 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -1098,13 +1098,18 @@ void CInode::store_parent(Context *fin) void CInode::_stored_parent(version_t v, Context *fin) { - if (v == inode.last_renamed_version) { - dout(10) << "stored_parent committed v" << v << ", removing from list" << dendl; - item_renamed_file.remove_myself(); - state_clear(STATE_DIRTYPARENT); + if (state_test(STATE_DIRTYPARENT)) { + if (v == inode.last_renamed_version) { + dout(10) << "stored_parent committed v" << v << ", removing from list" << dendl; + item_renamed_file.remove_myself(); + state_clear(STATE_DIRTYPARENT); + put(PIN_DIRTYPARENT); + } else { + dout(10) << "stored_parent committed v" << v << " < " << inode.last_renamed_version + << ", renamed again, not removing from list" << dendl; + } } else { - dout(10) << "stored_parent committed v" << v << " < " << inode.last_renamed_version - << ", renamed again, not removing from list" << dendl; + dout(10) << "stored_parent committed v" << v << ", tho i wasn't on the renamed_files list" << dendl; } if (fin) { fin->finish(0); diff --git a/src/mds/CInode.h b/src/mds/CInode.h index d37a6d2ada052..b851fc9ad3181 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -137,6 +137,7 @@ public: static const int PIN_NEEDSNAPFLUSH = 20; static const int PIN_DIRTYRSTAT = 21; static const int PIN_EXPORTINGCAPS = 22; + static const int PIN_DIRTYPARENT = 23; const char *pin_name(int p) { switch (p) { @@ -161,6 +162,7 @@ public: case PIN_STRAY: return "stray"; case PIN_NEEDSNAPFLUSH: return "needsnapflush"; case PIN_DIRTYRSTAT: return "dirtyrstat"; + case PIN_DIRTYPARENT: return "dirtyparent"; default: return generic_pin_name(p); } } diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c1eceff53351c..3166df6d29584 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -5372,8 +5372,13 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen if (desti->is_dir()) { mdr->ls->renamed_files.push_back(&desti->item_renamed_file); - desti->state_set(CInode::STATE_DIRTYPARENT); - dout(10) << "added dir to logsegment renamed_files list " << *desti << dendl; + if (!desti->state_test(CInode::STATE_DIRTYPARENT)) { + desti->state_set(CInode::STATE_DIRTYPARENT); + desti->get(CInode::PIN_DIRTYPARENT); + dout(10) << "added dir to logsegment renamed_files list " << *desti << dendl; + } else { + dout(10) << "re-added dir to logsegment renamed_files list " << *desti << dendl; + } } } else { // FIXME: fix up snaprealm! -- 2.39.5