mirror of
https://github.com/ceph/ceph
synced 2025-01-01 08:32:24 +00:00
mds: auth pin stray dir when purging stray inode
After stray inode gets added to purge queue, mds deletes stray dentry. MDS needs to make sure stray dir is not being fragmented. Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
This commit is contained in:
parent
02e15a20d9
commit
72dab35bd0
@ -198,7 +198,10 @@ void StrayManager::_purge_stray_purged(
|
||||
this, dn, mds->mdlog->get_current_segment()));
|
||||
} else {
|
||||
if (in->get_num_ref() != (int)in->is_dirty() ||
|
||||
dn->get_num_ref() != (int)dn->is_dirty() + !!in->get_num_ref() + 1/*PIN_PURGING*/) {
|
||||
dn->get_num_ref() !=
|
||||
(int)dn->is_dirty() +
|
||||
!!dn->state_test(CDentry::STATE_FRAGMENTING) +
|
||||
!!in->get_num_ref() + 1 /* PIN_PURGING */) {
|
||||
// Nobody should be taking new references to an inode when it
|
||||
// is being purged (aside from it were
|
||||
|
||||
@ -236,29 +239,32 @@ void StrayManager::_purge_stray_purged(
|
||||
void StrayManager::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls)
|
||||
{
|
||||
CInode *in = dn->get_linkage()->get_inode();
|
||||
CDir *dir = dn->get_dir();
|
||||
dout(10) << "_purge_stray_logged " << *dn << " " << *in << dendl;
|
||||
|
||||
ceph_assert(!in->state_test(CInode::STATE_RECOVERING));
|
||||
ceph_assert(!dir->is_frozen_dir());
|
||||
|
||||
bool new_dn = dn->is_new();
|
||||
|
||||
// unlink
|
||||
ceph_assert(dn->get_projected_linkage()->is_null());
|
||||
dn->dir->unlink_inode(dn, !new_dn);
|
||||
dir->unlink_inode(dn, !new_dn);
|
||||
dn->pop_projected_linkage();
|
||||
dn->mark_dirty(pdv, ls);
|
||||
|
||||
dn->dir->pop_and_dirty_projected_fnode(ls);
|
||||
dir->pop_and_dirty_projected_fnode(ls);
|
||||
|
||||
in->state_clear(CInode::STATE_ORPHAN);
|
||||
dn->state_clear(CDentry::STATE_PURGING | CDentry::STATE_PURGINGPINNED);
|
||||
dn->put(CDentry::PIN_PURGING);
|
||||
|
||||
|
||||
// drop dentry?
|
||||
if (new_dn) {
|
||||
dout(20) << " dn is new, removing" << dendl;
|
||||
dn->mark_clean();
|
||||
dn->dir->remove_dentry(dn);
|
||||
dir->remove_dentry(dn);
|
||||
}
|
||||
|
||||
// drop inode
|
||||
@ -267,6 +273,8 @@ void StrayManager::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *l
|
||||
in->mark_clean();
|
||||
mds->mdcache->remove_inode(in);
|
||||
|
||||
dir->auth_unpin(this);
|
||||
|
||||
if (mds->is_stopping())
|
||||
mds->mdcache->shutdown_export_stray_finish(ino);
|
||||
}
|
||||
@ -308,11 +316,11 @@ void StrayManager::enqueue(CDentry *dn, bool trunc)
|
||||
<< *dn << dendl;
|
||||
}
|
||||
|
||||
class C_OpenSnapParents : public StrayManagerContext {
|
||||
class C_RetryEnqueue : public StrayManagerContext {
|
||||
CDentry *dn;
|
||||
bool trunc;
|
||||
public:
|
||||
C_OpenSnapParents(StrayManager *sm_, CDentry *dn_, bool t) :
|
||||
C_RetryEnqueue(StrayManager *sm_, CDentry *dn_, bool t) :
|
||||
StrayManagerContext(sm_), dn(dn_), trunc(t) { }
|
||||
void finish(int r) override {
|
||||
sm->_enqueue(dn, trunc);
|
||||
@ -323,14 +331,23 @@ void StrayManager::_enqueue(CDentry *dn, bool trunc)
|
||||
{
|
||||
ceph_assert(started);
|
||||
|
||||
CDir *dir = dn->get_dir();
|
||||
if (!dir->can_auth_pin()) {
|
||||
dout(10) << " can't auth_pin (freezing?) " << *dir << ", waiting" << dendl;
|
||||
dir->add_waiter(CDir::WAIT_UNFREEZE, new C_RetryEnqueue(this, dn, trunc));
|
||||
return;
|
||||
}
|
||||
|
||||
CInode *in = dn->get_linkage()->get_inode();
|
||||
if (in->snaprealm &&
|
||||
!in->snaprealm->have_past_parents_open() &&
|
||||
!in->snaprealm->open_parents(new C_OpenSnapParents(this, dn, trunc))) {
|
||||
!in->snaprealm->open_parents(new C_RetryEnqueue(this, dn, trunc))) {
|
||||
// this can happen if the dentry had been trimmed from cache.
|
||||
return;
|
||||
}
|
||||
|
||||
dn->get_dir()->auth_pin(this);
|
||||
|
||||
if (trunc) {
|
||||
truncate(dn);
|
||||
} else {
|
||||
@ -739,6 +756,8 @@ void StrayManager::_truncate_stray_logged(CDentry *dn, LogSegment *ls)
|
||||
dn->state_clear(CDentry::STATE_PURGING | CDentry::STATE_PURGINGPINNED);
|
||||
dn->put(CDentry::PIN_PURGING);
|
||||
|
||||
dn->get_dir()->auth_unpin(this);
|
||||
|
||||
eval_stray(dn);
|
||||
|
||||
if (!dn->state_test(CDentry::STATE_PURGING) && mds->is_stopping())
|
||||
|
@ -103,7 +103,7 @@ protected:
|
||||
friend class StrayManagerContext;
|
||||
|
||||
friend class C_StraysFetched;
|
||||
friend class C_OpenSnapParents;
|
||||
friend class C_RetryEnqueue;
|
||||
friend class C_PurgeStrayLogged;
|
||||
friend class C_TruncateStrayLogged;
|
||||
friend class C_IO_PurgeStrayPurged;
|
||||
|
Loading…
Reference in New Issue
Block a user