From: Patrick Donnelly Date: Tue, 9 Jan 2024 19:04:45 +0000 (-0500) Subject: mds: add new inode quiescelock X-Git-Tag: v20.0.0~2328^2~34 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=a3e541f9992e5e264a8d9ecffd69787d722f88a0;p=ceph.git mds: add new inode quiescelock Signed-off-by: Patrick Donnelly --- diff --git a/doc/dev/mds_internals/locking.rst b/doc/dev/mds_internals/locking.rst index cfd934f3f31a5..4d21b895bea4a 100644 --- a/doc/dev/mds_internals/locking.rst +++ b/doc/dev/mds_internals/locking.rst @@ -17,6 +17,7 @@ MDS defines a handful of lock types associated with different metadata for an in CEPH_LOCK_DN - dentry CEPH_LOCK_DVERSION - dentry version + CEPH_LOCK_IQUIESCE - inode quiesce lock (a type of superlock) CEPH_LOCK_IVERSION - inode version CEPH_LOCK_IAUTH - mode, uid, gid CEPH_LOCK_ILINK - nlink diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 2454216802651..016645ab5b020 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -333,18 +333,24 @@ extern const char *ceph_mds_state_name(int s); */ #define CEPH_LOCK_DN (1 << 0) #define CEPH_LOCK_DVERSION (1 << 1) -#define CEPH_LOCK_ISNAP (1 << 4) /* snapshot lock. MDS internal */ -#define CEPH_LOCK_IPOLICY (1 << 5) /* policy lock on dirs. MDS internal */ -#define CEPH_LOCK_IFILE (1 << 6) -#define CEPH_LOCK_INEST (1 << 7) /* mds internal */ -#define CEPH_LOCK_IDFT (1 << 8) /* dir frag tree */ -#define CEPH_LOCK_IAUTH (1 << 9) -#define CEPH_LOCK_ILINK (1 << 10) -#define CEPH_LOCK_IXATTR (1 << 11) -#define CEPH_LOCK_IFLOCK (1 << 12) /* advisory file locks */ -#define CEPH_LOCK_IVERSION (1 << 13) /* mds internal */ - -#define CEPH_LOCK_IFIRST CEPH_LOCK_ISNAP +#define CEPH_LOCK_IQUIESCE (1 << 4) /* mds internal */ +#define CEPH_LOCK_ISNAP (1 << 5) /* snapshot lock. MDS internal */ +#define CEPH_LOCK_IPOLICY (1 << 6) /* policy lock on dirs. MDS internal */ +#define CEPH_LOCK_IFILE (1 << 7) +#define CEPH_LOCK_INEST (1 << 8) /* mds internal */ +#define CEPH_LOCK_IDFT (1 << 9) /* dir frag tree */ +#define CEPH_LOCK_IAUTH (1 << 10) +#define CEPH_LOCK_ILINK (1 << 11) +#define CEPH_LOCK_IXATTR (1 << 12) +#define CEPH_LOCK_IFLOCK (1 << 13) /* advisory file locks */ +#define CEPH_LOCK_IVERSION (1 << 14) /* mds internal */ + +#define CEPH_LOCK_IFIRST CEPH_LOCK_IQUIESCE +#define CEPH_LOCK_ILAST CEPH_LOCK_IVERSION + +static inline bool is_inode_lock(int l) { + return (CEPH_LOCK_IFIRST <= l && l <= CEPH_LOCK_ILAST); +} /* client_session ops */ diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 6d15908e54552..911bedf408feb 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -257,6 +257,8 @@ ostream& operator<<(ostream& out, const CInode& in) out << " " << in.xattrlock; if (!in.versionlock.is_sync_and_unlocked()) out << " " << in.versionlock; + if (!in.quiescelock.is_sync_and_unlocked()) + out << " " << in.quiescelock; // hack: spit out crap on which clients have caps if (in.get_inode()->client_ranges.size()) @@ -324,6 +326,7 @@ CInode::CInode(MDCache *c, bool auth, snapid_t f, snapid_t l) : item_dirty_dirfrag_nest(this), item_dirty_dirfrag_dirfragtree(this), pop(c->decayrate), + quiescelock(this, &quiescelock_type), versionlock(this, &versionlock_type), authlock(this, &authlock_type), linklock(this, &linklock_type), @@ -1660,6 +1663,7 @@ SimpleLock* CInode::get_lock(int type) case CEPH_LOCK_INEST: return &nestlock; case CEPH_LOCK_IFLOCK: return &flocklock; case CEPH_LOCK_IPOLICY: return &policylock; + case CEPH_LOCK_IQUIESCE: return &quiescelock; } return 0; } @@ -2203,6 +2207,13 @@ void CInode::encode_lock_state(int type, bufferlist& bl) case CEPH_LOCK_IPOLICY: encode_lock_ipolicy(bl); break; + + case CEPH_LOCK_IQUIESCE: { + ENCODE_START(1, 1, bl); + /* skeleton */ + ENCODE_FINISH(bl); + break; + } default: ceph_abort(); @@ -2270,6 +2281,13 @@ void CInode::decode_lock_state(int type, const bufferlist& bl) decode_lock_ipolicy(p); break; + case CEPH_LOCK_IQUIESCE: { + DECODE_START(1, p); + /* skeleton */ + DECODE_FINISH(p); + break; + } + default: ceph_abort(); } @@ -4264,8 +4282,8 @@ void CInode::_encode_locks_full(bufferlist& bl) encode(nestlock, bl); encode(flocklock, bl); encode(policylock, bl); - encode(loner_cap, bl); + encode(quiescelock, bl); } void CInode::_decode_locks_full(bufferlist::const_iterator& p) { @@ -4279,15 +4297,15 @@ void CInode::_decode_locks_full(bufferlist::const_iterator& p) decode(nestlock, p); decode(flocklock, p); decode(policylock, p); - decode(loner_cap, p); set_loner_cap(loner_cap); want_loner_cap = loner_cap; // for now, we'll eval() shortly. + decode(quiescelock, p); } void CInode::_encode_locks_state_for_replica(bufferlist& bl, bool need_recover) { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); authlock.encode_state_for_replica(bl); linklock.encode_state_for_replica(bl); dirfragtreelock.encode_state_for_replica(bl); @@ -4298,11 +4316,13 @@ void CInode::_encode_locks_state_for_replica(bufferlist& bl, bool need_recover) flocklock.encode_state_for_replica(bl); policylock.encode_state_for_replica(bl); encode(need_recover, bl); + quiescelock.encode_state_for_replica(bl); ENCODE_FINISH(bl); } void CInode::_encode_locks_state_for_rejoin(bufferlist& bl, int rep) { + // TODO versioning? authlock.encode_state_for_replica(bl); linklock.encode_state_for_replica(bl); dirfragtreelock.encode_state_for_rejoin(bl, rep); @@ -4312,11 +4332,12 @@ void CInode::_encode_locks_state_for_rejoin(bufferlist& bl, int rep) snaplock.encode_state_for_replica(bl); flocklock.encode_state_for_replica(bl); policylock.encode_state_for_replica(bl); + quiescelock.encode_state_for_replica(bl); } void CInode::_decode_locks_state_for_replica(bufferlist::const_iterator& p, bool is_new) { - DECODE_START(1, p); + DECODE_START(2, p); authlock.decode_state(p, is_new); linklock.decode_state(p, is_new); dirfragtreelock.decode_state(p, is_new); @@ -4329,6 +4350,11 @@ void CInode::_decode_locks_state_for_replica(bufferlist::const_iterator& p, bool bool need_recover; decode(need_recover, p); + + if (struct_v >= 2) { + quiescelock.decode_state(p, is_new); + } + if (need_recover && is_new) { // Auth mds replicated this inode while it's recovering. Auth mds may take xlock on the lock // and change the object when replaying unsafe requests. @@ -4341,6 +4367,7 @@ void CInode::_decode_locks_state_for_replica(bufferlist::const_iterator& p, bool snaplock.mark_need_recover(); flocklock.mark_need_recover(); policylock.mark_need_recover(); + quiescelock.mark_need_recover(); } DECODE_FINISH(p); } @@ -4356,6 +4383,7 @@ void CInode::_decode_locks_rejoin(bufferlist::const_iterator& p, MDSContext::vec snaplock.decode_state_rejoin(p, waiters, survivor); flocklock.decode_state_rejoin(p, waiters, survivor); policylock.decode_state_rejoin(p, waiters, survivor); + quiescelock.decode_state_rejoin(p, waiters, survivor); if (!dirfragtreelock.is_stable() && !dirfragtreelock.is_wrlocked()) eval_locks.push_back(&dirfragtreelock); @@ -4370,7 +4398,7 @@ void CInode::_decode_locks_rejoin(bufferlist::const_iterator& p, MDSContext::vec void CInode::encode_export(bufferlist& bl) { - ENCODE_START(5, 4, bl); + ENCODE_START(6, 6, bl); _encode_base(bl, mdcache->mds->mdsmap->get_up_features()); encode(state, bl); @@ -4421,7 +4449,7 @@ void CInode::finish_export() void CInode::decode_import(bufferlist::const_iterator& p, LogSegment *ls) { - DECODE_START(5, p); + DECODE_START(6, p); _decode_base(p); @@ -5099,6 +5127,10 @@ void CInode::dump(Formatter *f, int flags) const f->open_object_section("policylock"); policylock.dump(f); f->close_section(); + + f->open_object_section("quiescelock"); + quiescelock.dump(f); + f->close_section(); } if (flags & DUMP_STATE) { diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 1030b7466238a..1aaa5eadb5f52 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -1100,18 +1100,23 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counteris_rdlocked(&t->snaplock)) found_locked = true; if (!found_locked) { if (!t->snaplock.can_rdlock(client)) { - mdr->mark_event("failed to acquire snap lock"); + err = "failed to acquire snap lock"sv; t->snaplock.add_waiter(SimpleLock::WAIT_RD, new C_MDS_RetryRequest(mdcache, mdr)); goto failed; } @@ -172,7 +175,7 @@ bool Locker::try_rdlock_snap_layout(CInode *in, const MDRequestRef& mdr, if (want_layout && !found_layout) { if (!mdr->is_rdlocked(&t->policylock)) { if (!t->policylock.can_rdlock(client)) { - mdr->mark_event("failed to acquire policy lock"); + err = "failed to acquire policy lock"sv; t->policylock.add_waiter(SimpleLock::WAIT_RD, new C_MDS_RetryRequest(mdcache, mdr)); goto failed; } @@ -200,8 +203,11 @@ bool Locker::try_rdlock_snap_layout(CInode *in, const MDRequestRef& mdr, failed: dout(10) << __func__ << " failed" << dendl; - drop_locks(mdr.get(), nullptr); - mdr->drop_local_auth_pins(); + mdr->mark_event(err); + if (!dropped_locks) { + drop_locks(mdr.get(), nullptr); + mdr->drop_local_auth_pins(); + } return false; } @@ -224,7 +230,8 @@ struct MarkEventOnDestruct { bool Locker::acquire_locks(const MDRequestRef& mdr, MutationImpl::LockOpVec& lov, CInode *auth_pin_freeze, - bool auth_pin_nonblocking) + bool auth_pin_nonblocking, + bool skip_quiesce) { dout(10) << "acquire_locks " << *mdr << dendl; dout(20) << " lov = " << lov << dendl; @@ -242,10 +249,12 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, mustpin.insert(auth_pin_freeze); // xlocks + bool need_quiescelock = !skip_quiesce; for (size_t i = 0; i < lov.size(); ++i) { auto& p = lov[i]; SimpleLock *lock = p.lock; MDSCacheObject *object = lock->get_parent(); + auto t = lock->get_type(); if (p.is_xlock()) { if ((lock->get_type() == CEPH_LOCK_ISNAP || @@ -301,19 +310,30 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, lov.add_xlock(&dn->versionlock, i + 1); } } - if (lock->get_type() >= CEPH_LOCK_IFIRST && lock->get_type() != CEPH_LOCK_IVERSION) { - // inode version lock? - CInode *in = static_cast(object); - if (!in->is_auth()) - continue; - if (mdr->is_leader()) { - // leader. wrlock versionlock so we can pipeline inode updates to journal. - lov.add_wrlock(&in->versionlock, i + 1); - } else { - // peer. exclusively lock the inode version (i.e. block other journal updates). - // this makes rollback safe. - lov.add_xlock(&in->versionlock, i + 1); - } + if (is_inode_lock(t)) { + switch (t) { + case CEPH_LOCK_IVERSION: + case CEPH_LOCK_IQUIESCE: + break; + default: + CInode *in = static_cast(object); + if (need_quiescelock) { + need_quiescelock = false; + lov.add_rdlock(&in->quiescelock, i + 1); + } + if (!in->is_auth()) + continue; + // inode version lock? + if (mdr->is_leader()) { + // leader. wrlock versionlock so we can pipeline inode updates to journal. + lov.add_wrlock(&in->versionlock, i + 1); + } else { + // peer. exclusively lock the inode version (i.e. block other journal updates). + // this makes rollback safe. + lov.add_xlock(&in->versionlock, i + 1); + } + break; + } } } else if (p.is_wrlock()) { dout(20) << " must wrlock " << *lock << " " << *object << dendl; @@ -327,12 +347,21 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, << " in case we need to request a scatter" << dendl; mustpin.insert(object); } + if (need_quiescelock && is_inode_lock(t) && t != CEPH_LOCK_IQUIESCE) { + CInode *in = static_cast(object); + lov.add_rdlock(&in->quiescelock, i + 1); + need_quiescelock = false; + } } else if (p.is_remote_wrlock()) { dout(20) << " must remote_wrlock on mds." << p.wrlock_target << " " << *lock << " " << *object << dendl; mustpin.insert(object); + if (need_quiescelock && is_inode_lock(t) && t != CEPH_LOCK_IQUIESCE) { + CInode *in = static_cast(object); + lov.add_rdlock(&in->quiescelock, i + 1); + need_quiescelock = false; + } } else if (p.is_rdlock()) { - dout(20) << " must rdlock " << *lock << " " << *object << dendl; if (object->is_auth()) { mustpin.insert(object); @@ -342,6 +371,33 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, << " in case we need to request a rdlock" << dendl; mustpin.insert(object); } + + /* We treat rdlocks differently when adding the quiescelock. If the lock + * can be acquired immediately for reading without waiting + * (SimpleLock::can_rdlock), then skip adding the quiescelock. This is to + * allow some rdonly operations (like lookup) to proceed without blocking + * on the exclusively locked quiescelock. This is safe from deadlock (due + * to lock ordering) when Locker::acquire_locks is called more than once + * with different LockOpVectors for a given inode (already a dangerous + * thing to do) where there may be a wrlock/xlock in one set but not the + * other. The reason is simple: if Locker::acquire_locks ever adds the + * quiescelock, it is always the first lock to be acquired, and if it is + * xlocked, then all locks are dropped (s.f. + * Locker::handle_quiesce_failure). So adding the quiescelock can never + * contribute to deadlock. + */ + + if (need_quiescelock && !mdr->is_rdlocked(lock)) { + /* Can we get the lock without waiting? */ + if (!lock->can_rdlock(client)) { + /* To prevent deadlock where an op holds a parent snaplock + * (Locker::try_rdlock_snap_layout), add quiescelock. + */ + CInode *in = static_cast(object); + lov.add_rdlock(&in->quiescelock, i + 1); + need_quiescelock = false; + } + } } else { ceph_assert(0 == "locker unknown lock operation"); } @@ -508,6 +564,7 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, // make sure they match currently acquired locks. for (const auto& p : lov) { auto lock = p.lock; + auto t = lock->get_type(); if (p.is_xlock()) { if (mdr->is_xlocked(lock)) { dout(10) << " already xlocked " << *lock << " " << *lock->get_parent() << dendl; @@ -516,7 +573,11 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, if (mdr->locking && lock != mdr->locking) cancel_locking(mdr.get(), &issue_set); if (!xlock_start(lock, mdr)) { - marker.message = "failed to xlock, waiting"; + if (t == CEPH_LOCK_IQUIESCE) { + handle_quiesce_failure(mdr, marker.message); + } else { + marker.message = "failed to xlock, waiting"; + } goto out; } dout(10) << " got xlock on " << *lock << " " << *lock->get_parent() << dendl; @@ -542,18 +603,26 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, if (p.is_remote_wrlock()) { // nowait if we have already gotten remote wrlock if (!wrlock_try(lock, mdr, _client)) { - marker.message = "failed to wrlock, dropping remote wrlock and waiting"; // can't take the wrlock because the scatter lock is gathering. need to // release the remote wrlock, so that the gathering process can finish. ceph_assert(it != mdr->locks.end()); remote_wrlock_finish(it, mdr.get()); remote_wrlock_start(lock, p.wrlock_target, mdr); + if (t == CEPH_LOCK_IQUIESCE) { + handle_quiesce_failure(mdr, marker.message); + } else { + marker.message = "failed to wrlock, dropping remote wrlock and waiting"; + } goto out; } } else { if (!wrlock_start(p, mdr)) { ceph_assert(!p.is_remote_wrlock()); - marker.message = "failed to wrlock, waiting"; + if (t == CEPH_LOCK_IQUIESCE) { + handle_quiesce_failure(mdr, marker.message); + } else { + marker.message = "failed to wrlock, waiting"; + } goto out; } } @@ -584,7 +653,11 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, } if (!rdlock_start(lock, mdr)) { - marker.message = "failed to rdlock, waiting"; + if (t == CEPH_LOCK_IQUIESCE) { + handle_quiesce_failure(mdr, marker.message); + } else { + marker.message = "failed to rdlock, waiting"; + } goto out; } dout(10) << " got rdlock on " << *lock << " " << *lock->get_parent() << dendl; @@ -600,6 +673,23 @@ bool Locker::acquire_locks(const MDRequestRef& mdr, return result; } +/* Dropping *all* locks here is necessary so parent directory + * snap/layout/quiesce locks are unlocked for a future mksnap. This is the + * primary purpose of the new quiescelock. An op, e.g. getattr, cannot block + * waiting for another lock held by quiesce_subvolume_inode, e.g. filelock, + * which will prevent a mksnap on a subvolume inode (because getattr will + * already have gotten parent snaplocks, see Locker::try_rdlock_snap_layout). + */ + +void Locker::handle_quiesce_failure(const MDRequestRef& mdr, std::string_view& marker) +{ + dout(10) << " failed to acquire quiesce lock; dropping all locks" << dendl; + marker = "failed to acquire quiesce lock"sv; + drop_locks(mdr.get(), NULL); + mdr->drop_local_auth_pins(); +} + + void Locker::notify_freeze_waiter(MDSCacheObject *o) { CDir *dir = NULL; @@ -1336,6 +1426,8 @@ bool Locker::eval(CInode *in, int mask, bool caps_imported) eval_any(&in->flocklock, &need_issue, &finishers, caps_imported); if (mask & CEPH_LOCK_IPOLICY) eval_any(&in->policylock, &need_issue, &finishers, caps_imported); + if (mask & CEPH_LOCK_IQUIESCE) + eval_any(&in->quiescelock, &need_issue, &finishers, caps_imported); // drop loner? if (in->is_auth() && in->is_head() && in->get_wanted_loner() != in->get_loner()) { @@ -4418,6 +4510,7 @@ SimpleLock *Locker::get_lock(int lock_type, const MDSCacheObjectInfo &info) case CEPH_LOCK_ISNAP: case CEPH_LOCK_IFLOCK: case CEPH_LOCK_IPOLICY: + case CEPH_LOCK_IQUIESCE: { CInode *in = mdcache->get_inode(info.ino, info.snapid); if (!in) { @@ -4434,6 +4527,7 @@ SimpleLock *Locker::get_lock(int lock_type, const MDSCacheObjectInfo &info) case CEPH_LOCK_ISNAP: return &in->snaplock; case CEPH_LOCK_IFLOCK: return &in->flocklock; case CEPH_LOCK_IPOLICY: return &in->policylock; + case CEPH_LOCK_IQUIESCE: return &in->quiescelock; } } @@ -4459,6 +4553,7 @@ void Locker::handle_lock(const cref_t &m) switch (lock->get_type()) { case CEPH_LOCK_DN: + case CEPH_LOCK_IQUIESCE: case CEPH_LOCK_IAUTH: case CEPH_LOCK_ILINK: case CEPH_LOCK_ISNAP: diff --git a/src/mds/Locker.h b/src/mds/Locker.h index eed421ba0db9e..e3ecdf8131b14 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -54,7 +54,8 @@ public: bool acquire_locks(const MDRequestRef& mdr, MutationImpl::LockOpVec& lov, CInode *auth_pin_freeze=NULL, - bool auth_pin_nonblocking=false); + bool auth_pin_nonblocking=false, + bool skip_quiesce=false); bool try_rdlock_snap_layout(CInode *in, const MDRequestRef& mdr, int n=0, bool want_layout=false); @@ -259,6 +260,8 @@ private: friend class LockerContext; friend class LockerLogContext; + void handle_quiesce_failure(const MDRequestRef& mdr, std::string_view& marker); + bool any_late_revoking_caps(xlist const &revoking, double timeout) const; uint64_t calc_new_max_size(const CInode::inode_const_ptr& pi, uint64_t size); __u32 get_xattr_total_length(CInode::mempool_xattr_map &xattr); diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index a3e9d31ded141..b5690f4e2d780 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -1698,6 +1698,7 @@ void Migrator::finish_export_inode(CInode *in, mds_rank_t peer, in->snaplock.export_twiddle(); in->flocklock.export_twiddle(); in->policylock.export_twiddle(); + in->quiescelock.export_twiddle(); // mark auth ceph_assert(in->is_auth()); @@ -3245,6 +3246,10 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::const_iterator& blp, if (in->policylock.is_stable() && in->policylock.get_state() != LOCK_SYNC) mds->locker->try_eval(&in->policylock, NULL); + + if (in->quiescelock.is_stable() && + in->quiescelock.get_state() != LOCK_SYNC) + mds->locker->try_eval(&in->quiescelock, NULL); } void Migrator::decode_import_inode_caps(CInode *in, bool auth_cap, diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 5749bfa7f263d..d3d14a61ce6fd 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3076,8 +3076,9 @@ void Server::dispatch_peer_request(const MDRequestRef& mdr) replycode = MMDSPeerRequest::OP_WRLOCKACK; break; } - - if (!mds->locker->acquire_locks(mdr, lov)) + + // don't add quiescelock, let the peer acquire that rdlock themselves + if (!mds->locker->acquire_locks(mdr, lov, nullptr, {}, false, true)) return; // ack @@ -4890,6 +4891,8 @@ void Server::handle_client_readdir(const MDRequestRef& mdr) return; } + /* readdir can add dentries to cache: acquire the quiescelock */ + lov.add_rdlock(&diri->quiescelock); lov.add_rdlock(&diri->filelock); lov.add_rdlock(&diri->dirfragtreelock); diff --git a/src/mds/SimpleLock.cc b/src/mds/SimpleLock.cc index 4dea69f2b5d11..43f710ec68a50 100644 --- a/src/mds/SimpleLock.cc +++ b/src/mds/SimpleLock.cc @@ -57,6 +57,7 @@ int SimpleLock::get_wait_shift() const { case CEPH_LOCK_INEST: return 9*SimpleLock::WAIT_BITS; case CEPH_LOCK_IFLOCK: return 10*SimpleLock::WAIT_BITS; case CEPH_LOCK_IPOLICY: return 11*SimpleLock::WAIT_BITS; + case CEPH_LOCK_IQUIESCE: return 12*SimpleLock::WAIT_BITS; default: ceph_abort(); } diff --git a/src/mds/SimpleLock.h b/src/mds/SimpleLock.h index 8d3ea32e2442c..d0b6578302d77 100644 --- a/src/mds/SimpleLock.h +++ b/src/mds/SimpleLock.h @@ -41,6 +41,7 @@ struct LockType { explicit LockType(int t) : type(t) { switch (type) { case CEPH_LOCK_DN: + case CEPH_LOCK_IQUIESCE: case CEPH_LOCK_IAUTH: case CEPH_LOCK_ILINK: case CEPH_LOCK_IXATTR: @@ -150,6 +151,7 @@ public: case CEPH_LOCK_ISNAP: return "isnap"; case CEPH_LOCK_IFLOCK: return "iflock"; case CEPH_LOCK_IPOLICY: return "ipolicy"; + case CEPH_LOCK_IQUIESCE: return "iquiesce"; default: return "unknown"; } }