dout(7) << "can_fragment: i won't fragment mdsdir or .ceph" << dendl;
return false;
}
+ if (diri->is_quiesced()) {
+ dout(7) << "can_fragment: directory inode is quiesced" << dendl;
+ return false;
+ }
for (const auto& dir : dirs) {
if (dir->scrub_is_in_progress()) {
mdr->aborted = true;
if (!(mdr->locking_state & MutationImpl::ALL_LOCKED)) {
+ /* If quiescelock cannot be wrlocked, we cannot block with tree frozen.
+ * Otherwise, this can create deadlock where some quiesce_inode requests
+ * (on inodes in the dirfrag) are blocked on a frozen tree and the
+ * fragment_dir request is blocked on the queiscelock for the directory
+ * inode's quiescelock.
+ */
+ if (!mdr->is_wrlocked(&diri->quiescelock) && !diri->quiescelock.can_wrlock()) {
+ mdr->aborted = true;
+ }
+
if (!mdr->aborted) {
MutationImpl::LockOpVec lov;
lov.add_wrlock(&diri->dirfragtreelock);
}
if (mdr->aborted) {
- dout(10) << " can't auth_pin " << *diri << ", requeuing dir "
+ dout(10) << " can't auth_pin or acquire quiescelock on "
+ << *diri << ", requeuing dir "
<< info.dirs.front()->dirfrag() << dendl;
if (info.bits > 0)
mds->balancer->queue_split(info.dirs.front(), false);
&& parent->get_parent_dir()->ino() != MDS_INO_MDSDIR(dest)) {
dout(7) << "Cannot export to mds." << dest << " " << *dir << ": in stray directory" << dendl;
return;
+ } else if (dir->inode->is_quiesced()) {
+ dout(7) << "Cannot export to mds." << dest << " " << *dir << ": is quiesced" << dendl;
+ return;
}
if (unlikely(g_conf()->mds_thrash_exports)) {
void Migrator::dispatch_export_dir(const MDRequestRef& mdr, int count)
{
CDir *dir = mdr->more()->export_dir;
+ auto* diri = dir->get_inode();
dout(7) << *mdr << " " << *dir << dendl;
map<CDir*,export_state_t>::iterator it = export_state.find(dir);
// locks?
if (!(mdr->locking_state & MutationImpl::ALL_LOCKED)) {
+ /* If quiescelock cannot be wrlocked, we cannot block with tree frozen.
+ * Otherwise, this can create deadlock where some quiesce_inode requests
+ * (on inodes in the dirfrag) are blocked on a frozen tree and the
+ * fragment_dir request is blocked on the queiscelock for the directory
+ * inode's quiescelock.
+ */
+ if (!mdr->is_wrlocked(&diri->quiescelock) && !diri->quiescelock.can_wrlock()) {
+ mdr->aborted = true;
+ export_try_cancel(dir);
+ return;
+ }
+
MutationImpl::LockOpVec lov;
// If auth MDS of the subtree root inode is neither the exporter MDS
// nor the importer MDS and it gathers subtree root's fragstat/neststat