From: Yan, Zheng Date: Sat, 18 Jan 2014 00:27:02 +0000 (+0800) Subject: mds: allow fragmenting subtree dirfrags X-Git-Tag: v0.78~165^2~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ee7ac6fc66bca0e677af864f1a8fad758d77a2ca;p=ceph.git mds: allow fragmenting subtree dirfrags We can't wait until object becomes auth pinnable after freezing a dirfrag/subtree, because it can cause deadlock. Current fragmenting dirfrag code checks if the directory inode is auth pinnable, then calls Locker::acquire_locks(). It avoids deadlock, but also forbids fragmenting subtree dirfrags. We can get rid of the limitation by using 'nonlocking auth pin' mode of Locker::acquire_locks(). Signed-off-by: Yan, Zheng --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 26ca882f7c5b..22ddb143e193 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -11401,31 +11401,29 @@ void MDCache::dispatch_fragment_dir(MDRequest *mdr) dout(10) << "dispatch_fragment_dir " << basedirfrag << " bits " << info.bits << " on " << *diri << dendl; - - // avoid freeze dir deadlock - if (!mdr->is_auth_pinned(diri)) { - if (!diri->can_auth_pin()) { - dout(10) << " can't auth_pin " << *diri << ", requeuing dir " - << info.dirs.front()->dirfrag() << dendl; - if (info.bits > 0) - mds->balancer->queue_split(info.dirs.front()); - else - mds->balancer->queue_merge(info.dirs.front()); - fragment_unmark_unfreeze_dirs(info.dirs); - fragments.erase(it); - request_finish(mdr); - return; - } - mdr->auth_pin(diri); + if (!mdr->aborted) { + set rdlocks, wrlocks, xlocks; + wrlocks.insert(&diri->dirfragtreelock); + // prevent a racing gather on any other scatterlocks too + wrlocks.insert(&diri->nestlock); + wrlocks.insert(&diri->filelock); + if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks, NULL, NULL, true)) + if (!mdr->aborted) + return; } - set rdlocks, wrlocks, xlocks; - wrlocks.insert(&diri->dirfragtreelock); - // prevent a racing gather on any other scatterlocks too - wrlocks.insert(&diri->nestlock); - wrlocks.insert(&diri->filelock); - if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks)) + if (mdr->aborted) { + dout(10) << " can't auth_pin " << *diri << ", requeuing dir " + << info.dirs.front()->dirfrag() << dendl; + if (info.bits > 0) + mds->balancer->queue_split(info.dirs.front()); + else + mds->balancer->queue_merge(info.dirs.front()); + fragment_unmark_unfreeze_dirs(info.dirs); + fragments.erase(it); + request_finish(mdr); return; + } mdr->ls = mds->mdlog->get_current_segment(); EFragment *le = new EFragment(mds->mdlog, EFragment::OP_PREPARE, basedirfrag, info.bits);