mirror of
https://github.com/ceph/ceph
synced 2025-03-30 07:19:14 +00:00
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.
This commit is contained in:
parent
961e186d47
commit
d715338110
@ -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<CDentry*> 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<Context*> ls;
|
||||
dir->inode->put_scatter_pin(ls);
|
||||
mds->queue_waiters(ls);
|
||||
}
|
||||
|
||||
void Migrator::export_finish(CDir *dir)
|
||||
|
@ -81,8 +81,6 @@ protected:
|
||||
// export fun
|
||||
map<CDir*,int> export_state;
|
||||
map<CDir*,int> export_peer;
|
||||
map<CDir*,int> export_parent_rdlocked; // bit set => rdlocked
|
||||
map<CDir*,int> export_parent_wrlocked; // bit set => wrlocked
|
||||
//map<CDir*,list<bufferlist> > export_data; // only during EXPORTING state
|
||||
map<CDir*,set<int> > export_warning_ack_waiting;
|
||||
map<CDir*,set<int> > 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);
|
||||
|
Loading…
Reference in New Issue
Block a user