From d715338110a120e14b36f895a1f33e832bcbabc5 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 22 Sep 2010 15:42:52 -0700 Subject: [PATCH] mds: use scatter pins for migration instead of rd/wrlocks This is simpler (for the migrator), and wrlocks allow scatter_writebehind, which is a no-no for a frozen tree. By pinning the frozen dir's parent inode, we prevent any scatter or unscatter operations from implicitly updating metadata within the frozen root dirfrag. --- src/mds/Migrator.cc | 58 +++++++++------------------------------------ src/mds/Migrator.h | 4 ---- 2 files changed, 11 insertions(+), 51 deletions(-) diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index cd7f72959218f..94915d53d0725 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -548,33 +548,6 @@ public: * public method to initiate an export. * will fail if the directory is freezing, frozen, unpinnable, or root. */ -static void rd_or_wr_lock(ScatterLock *lock, int *rd, int *wr) -{ - if (lock->can_rdlock(-1)) { - lock->get_rdlock(); - *rd |= lock->get_type(); - } else { - lock->get_wrlock(); - *wr |= lock->get_type(); - } -} - -static void rd_or_wr_unlock(MDS *mds, ScatterLock *lock, int rd, int wr) -{ - if (rd & lock->get_type()) - mds->locker->rdlock_finish(lock, NULL); - else - mds->locker->wrlock_finish(lock, NULL); -} - -void Migrator::drop_parent_rd_wr_locks(CInode *in, int rd, int wr) -{ - rd_or_wr_unlock(mds, &in->filelock, rd, wr); - rd_or_wr_unlock(mds, &in->nestlock, rd, wr); - rd_or_wr_unlock(mds, &in->dirfragtreelock, rd, wr); -} - - void Migrator::export_dir(CDir *dir, int dest) { dout(7) << "export_dir " << *dir << " to " << dest << dendl; @@ -616,10 +589,8 @@ void Migrator::export_dir(CDir *dir, int dest) } // pin parent scatterlocks? CInode *diri = dir->inode; - if ((!diri->filelock.can_rdlock(-1) && !diri->filelock.can_wrlock(diri->get_loner())) || - (!diri->nestlock.can_rdlock(-1) && !diri->nestlock.can_wrlock(diri->get_loner())) || - (!diri->dirfragtreelock.can_rdlock(-1) && !diri->dirfragtreelock.can_wrlock(diri->get_loner()))) { - dout(7) << "export_dir couldn't rd|wrlock parent inode file+nest+dftlock, failing. " << *diri << dendl; + if (!diri->can_scatter_pin()) { + dout(7) << "export_dir couldn't pin parent inode scatterlocks, failing. " << *diri << dendl; return; } @@ -689,9 +660,7 @@ void Migrator::export_frozen(CDir *dir) CInode *diri = dir->inode; if (!mds->locker->dentry_can_rdlock_trace(trace) || - (!diri->filelock.can_rdlock(-1) && !diri->filelock.can_wrlock(diri->get_loner())) || - (!diri->nestlock.can_rdlock(-1) && !diri->nestlock.can_wrlock(diri->get_loner())) || - (!diri->dirfragtreelock.can_rdlock(-1) && !diri->dirfragtreelock.can_wrlock(diri->get_loner()))) { + !diri->can_scatter_pin()) { dout(7) << "export_dir couldn't rdlock path or rd|wrlock parent inode file+nest+dftlock, failing. " << *diri << dendl; @@ -711,16 +680,10 @@ void Migrator::export_frozen(CDir *dir) dout(10) << " taking locks on path, parent inode scatterlocks" << dendl; // rdlock path mds->locker->dentry_anon_rdlock_trace_start(trace); - - // rd or wrlock parent inode scatterlocks - // this prevents accounted_fragstat updates while we are frozen - int rdlocked = 0, wrlocked = 0; - rd_or_wr_lock(&diri->filelock, &rdlocked, &wrlocked); - rd_or_wr_lock(&diri->nestlock, &rdlocked, &wrlocked); - rd_or_wr_lock(&diri->dirfragtreelock, &rdlocked, &wrlocked); - export_parent_rdlocked[dir] = rdlocked; - export_parent_wrlocked[dir] = wrlocked; - dout(10) << " dir inode now locked " << *diri << dendl; + + // pin scatterlocks + diri->get_scatter_pin(); + dout(10) << " dir inode now scatter pinned " << *diri << dendl; cache->show_subtrees(); @@ -1407,9 +1370,10 @@ void Migrator::export_unlock(CDir *dir) vector trace; cache->make_trace(trace, dir->inode); mds->locker->dentry_anon_rdlock_trace_finish(trace); - drop_parent_rd_wr_locks(dir->inode, export_parent_rdlocked[dir], export_parent_wrlocked[dir]); - export_parent_rdlocked.erase(dir); - export_parent_wrlocked.erase(dir); + + list ls; + dir->inode->put_scatter_pin(ls); + mds->queue_waiters(ls); } void Migrator::export_finish(CDir *dir) diff --git a/src/mds/Migrator.h b/src/mds/Migrator.h index 40ce4b413ad62..fa02007765bac 100644 --- a/src/mds/Migrator.h +++ b/src/mds/Migrator.h @@ -81,8 +81,6 @@ protected: // export fun map export_state; map export_peer; - map export_parent_rdlocked; // bit set => rdlocked - map export_parent_wrlocked; // bit set => wrlocked //map > export_data; // only during EXPORTING state map > export_warning_ack_waiting; map > export_notify_ack_waiting; @@ -167,8 +165,6 @@ public: } - void drop_parent_rd_wr_locks(CInode *in, int rd, int wr); - // -- misc -- void handle_mds_failure_or_stop(int who); -- 2.39.5