@@ -13623,11 +13623,39 @@ void MDCache::dispatch_quiesce_inode(const MDRequestRef& mdr)
1362313623
1362413624 if (!(mdr->locking_state & MutationImpl::ALL_LOCKED)) {
1362513625 MutationImpl::LockOpVec lov;
13626- lov.add_rdlock (&in->authlock );
13627- lov.add_rdlock (&in->filelock );
13628- lov.add_rdlock (&in->linklock );
13626+
1362913627 lov.add_xlock (&in->quiescelock ); /* !! */
13630- lov.add_rdlock (&in->xattrlock );
13628+
13629+ if (in->is_auth ()) {
13630+ if (splitauth) {
13631+ // xlock the file to let the Fb clients stay with buffered writes.
13632+ // While this will unnecesarily revoke rd caps, it's not as
13633+ // big of an overhead compared to having the Fb clients flush
13634+ // their buffers, which evidently can lead to the quiesce timeout
13635+ // We'll drop the lock after all clients conform to this request
13636+ // so the file will be still readable during the quiesce after
13637+ // the interested clients receive their Fr back
13638+ //
13639+ // NB: this will also wrlock the versionlock
13640+ lov.add_xlock (&in->filelock );
13641+ } else {
13642+ // if splitauth == false then we won't drop the lock after acquisition (see below)
13643+ // we can't afford keeping it as xlock for a long time, so we'll have to deal
13644+ // with the potential quiesce timeout on high-load systems.
13645+ // The reason we're OK with this is that splitauth is enabled by default,
13646+ // and really should not be ever disabled outside of the test setups
13647+ // TODO: consider removing the `splitauth` config option completely.
13648+ lov.add_rdlock (&in->filelock );
13649+ }
13650+ // The rest of caps-related locks - rdlock to revoke write caps
13651+ lov.add_rdlock (&in->authlock );
13652+ lov.add_rdlock (&in->linklock );
13653+ lov.add_rdlock (&in->xattrlock );
13654+ } else {
13655+ // replica will follow suite and move to LOCK_LOCK state
13656+ // as a result of the auth taking the above locks.
13657+ }
13658+
1363113659 if (!mds->locker ->acquire_locks (mdr, lov, nullptr , {in}, false , true )) {
1363213660 return ;
1363313661 }
@@ -13645,13 +13673,17 @@ void MDCache::dispatch_quiesce_inode(const MDRequestRef& mdr)
1364513673 return ;
1364613674 }
1364713675
13648- if (splitauth) {
13676+ if (in-> is_auth () && splitauth) {
1364913677 /* Once we have the queiscelock, we no longer need these locks. However,
1365013678 * if splitauth==false, the replicas do not try quiescing so we must keep
1365113679 * them locked.
1365213680 */
1365313681 mds->locker ->drop_lock (mdr.get (), &in->authlock );
1365413682 mds->locker ->drop_lock (mdr.get (), &in->filelock );
13683+ // versionlock will be taken automatically for the file xlock.
13684+ // We don't really need it, but it doesn't make sense to
13685+ // change the Locker logic just for this flow
13686+ mds->locker ->drop_lock (mdr.get (), &in->versionlock );
1365513687 mds->locker ->drop_lock (mdr.get (), &in->linklock );
1365613688 mds->locker ->drop_lock (mdr.get (), &in->xattrlock );
1365713689 }
0 commit comments