From 19949f6d608481a0bf3c680228dc62ed155ba006 Mon Sep 17 00:00:00 2001 From: Greg Farnum Date: Fri, 3 Jun 2011 09:53:20 -0700 Subject: [PATCH] mds: Clean up _rename_prepare journaling This has been broken for a while in terms of journaling things the MDS isn't auth for. This patch should fix that, and adds a few asserts to that effect. Also adds a new not_journaling flag to _rename_prepare for those cases which call the function and then discard the bufferlist results. Signed-off-by: Greg Farnum --- src/mds/Server.cc | 35 +++++++++++++++++++++++++---------- src/mds/Server.h | 6 +++++- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index ccccf8f0126f2..559f97715a5d5 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -5067,7 +5067,8 @@ version_t Server::_rename_prepare_import(MDRequest *mdr, CDentry *srcdn, bufferl void Server::_rename_prepare(MDRequest *mdr, EMetaBlob *metablob, bufferlist *client_map_bl, - CDentry *srcdn, CDentry *destdn, CDentry *straydn) + CDentry *srcdn, CDentry *destdn, CDentry *straydn, + bool not_journaling) { dout(10) << "_rename_prepare " << *mdr << " " << *srcdn << " " << *destdn << dendl; if (straydn) dout(10) << " straydn " << *straydn << dendl; @@ -5201,23 +5202,34 @@ void Server::_rename_prepare(MDRequest *mdr, } // dest + /* FIXME: this looks to largely assume that a remote + * src implies a local dest, that's not good -- we might be + * auth for the srci or the desti without being auth on the dentries */ if (srcdnl->is_remote()) { + assert(not_journaling || srcdn->is_auth() ||destdn->is_auth() || + (srcdnl->get_inode() && srcdnl->get_inode()->is_auth()) || + (destdnl->get_inode() && destdnl->get_inode()->is_auth())); if (!linkmerge) { - if (!destdnl->is_null()) + if (destdn->is_auth() && !destdnl->is_null()) mdcache->journal_cow_dentry(mdr, metablob, destdn, CEPH_NOSNAP, 0, destdnl); else destdn->first = MAX(destdn->first, next_dest_snap); - metablob->add_remote_dentry(destdn, true, srcdnl->get_remote_ino(), srcdnl->get_remote_d_type()); - if (srcdnl->get_inode()->is_auth()) { - mdcache->journal_cow_dentry(mdr, metablob, srcdnl->get_inode()->get_parent_dn(), CEPH_NOSNAP, 0, srcdnl); + + if (destdn->is_auth()) + metablob->add_remote_dentry(destdn, true, srcdnl->get_remote_ino(), srcdnl->get_remote_d_type()); + if (srcdnl->get_inode()->get_parent_dn()->is_auth()) { // it's remote + mdcache->journal_cow_dentry(mdr, metablob, srcdnl->get_inode()->get_parent_dn(), CEPH_NOSNAP, 0, srcdnl); ji = metablob->add_primary_dentry(srcdnl->get_inode()->get_parent_dn(), true, srcdnl->get_inode()); } } else { - if (!destdnl->is_null()) + if (destdn->is_auth() && !destdnl->is_null()) mdcache->journal_cow_dentry(mdr, metablob, destdn, CEPH_NOSNAP, 0, destdnl); else destdn->first = MAX(destdn->first, next_dest_snap); - metablob->add_primary_dentry(destdn, true, destdnl->get_inode()); + + if (destdn->is_auth() || + (destdnl->get_inode() && destdnl->get_inode()->is_auth())) + metablob->add_primary_dentry(destdn, true, destdnl->get_inode()); } } else if (srcdnl->is_primary()) { // project snap parent update? @@ -5225,11 +5237,14 @@ void Server::_rename_prepare(MDRequest *mdr, if (destdn->is_auth() && srcdnl->get_inode()->snaprealm) srcdnl->get_inode()->project_past_snaprealm_parent(dest_realm, snapbl); - if (!destdnl->is_null()) + if (destdn->is_auth() && !destdnl->is_null()) mdcache->journal_cow_dentry(mdr, metablob, destdn, CEPH_NOSNAP, 0, destdnl); else destdn->first = MAX(destdn->first, next_dest_snap); - ji = metablob->add_primary_dentry(destdn, true, srcdnl->get_inode(), 0, &snapbl); + + if (destdn->is_auth() || + (destdnl->get_inode() && destdnl->get_inode()->is_auth())) + ji = metablob->add_primary_dentry(destdn, true, srcdnl->get_inode(), 0, &snapbl); } // src @@ -5589,7 +5604,7 @@ void Server::handle_slave_rename_prep(MDRequest *mdr) // prepare anyway; this may twiddle dir_auth EMetaBlob blob; bufferlist blah; - _rename_prepare(mdr, &blob, &blah, srcdn, destdn, straydn); + _rename_prepare(mdr, &blob, &blah, srcdn, destdn, straydn, true); _logged_slave_rename(mdr, srcdn, destdn, straydn); } } diff --git a/src/mds/Server.h b/src/mds/Server.h index bbe8c05d0bbe5..8a7e3d38c9054 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -210,7 +210,11 @@ public: version_t _rename_prepare_import(MDRequest *mdr, CDentry *srcdn, bufferlist *client_map_bl); void _rename_prepare(MDRequest *mdr, EMetaBlob *metablob, bufferlist *client_map_bl, - CDentry *srcdn, CDentry *destdn, CDentry *straydn); + CDentry *srcdn, CDentry *destdn, CDentry *straydn, + bool not_journaling=false); + /* set not_journaling=true if you're going to discard the results -- + * this bypasses the asserts to make sure we're journaling the right + * things on the right nodes */ void _rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDentry *straydn); // slaving -- 2.39.5